001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.server.processor;
018
019import java.io.*;
020
021import org.apache.juneau.http.response.*;
022import org.apache.juneau.rest.server.*;
023
024import jakarta.servlet.http.*;
025
026/**
027 * Defines the interface for processors that convert POJOs to appropriate HTTP responses.
028 *
029 * <p>
030 * The REST Server API uses the concept of registered response processors for converting objects returned by REST
031 * methods or set through {@link RestResponse#setContent(Object)} into appropriate HTTP responses.
032 *
033 * <p>
034 * Response processors can be associated with REST resources via the following:
035 * <ul>
036 *    <li class='ja'>{@link Rest#responseProcessors}
037 *    <li class='ja'>{@link Rest#responseProcessors()}
038 * </ul>
039 *
040 * <p>
041 * Response processors can be used to process POJOs that cannot normally be handled through Juneau serializers, or
042 * because it's simply easier to define response processors for special cases.
043 *
044 * <p>
045 * The following example shows how to create a response processor to handle special <c>Foo</c> objects outside the
046 * normal Juneau architecture.
047 * <p class='bjava'>
048 *    <ja>@Rest</ja>(
049 *       path=<js>"/example"</js>,
050 *       responseProcessors=FooProcessor.<jk>class</jk>
051 *    )
052 *    <jk>public class</jk> Example <jk>extends</jk> BasicRestServlet {
053 *
054 *       <ja>@RestGet</ja>(<js>"/"</js>)
055 *       <jk>public</jk> Foo test1() {
056 *          <jk>return new</jk> Foo(<js>"123"</js>);
057 *       }
058 *
059 *       <jk>public static class</jk> FooProcessor <jk>implements</jk> ResponseProcessor {
060 *          <ja>@Override</ja>
061 *          <jk>public int</jk> process(RestOpSession <jv>opSession</jv>) {
062 *
063 *             RestResponse <jv>res</jv> = <jv>opSession</jv>.getResponse();
064 *             Foo <jv>foo</jv> = <jv>res</jv>.getContent(Foo.<jk>class</jk>);
065 *
066 *             <jk>if</jk> (<jv>foo</jv> == <jk>null</jk>)
067 *                <jk>return</jk> <jsf>NEXT</jsf>;  <jc>// Let the next processor handle it.</jc>
068 *
069 *             <jc>// Set some headers and content.</jc>
070 *             <jv>res</jv>.setHeader(<js>"Foo-ID"</js>, <jv>foo</jv>.getId());
071 *             <jv>res</jv>.getWriter().write(<js>"foo.id="</js> + <jv>foo</jv>.getId());
072 *
073 *             <jk>return</jk> <jsf>FINISHED</jsf>;  <jc>// We handled it.</jc>
074 *          }
075 *       }
076 *    }
077 * </p>
078 *
079 * <h5 class='section'>See Also:</h5><ul>
080 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ResponseProcessors">Response Processors</a>
081 * </ul>
082 */
083public interface ResponseProcessor {
084
085   /**
086    * Return code indicating to proceed to the next response processor in the chain.
087    */
088   int NEXT = 0;
089
090   /**
091    * Return code indicating that processing is complete and to exit the chain.
092    */
093   int FINISHED = 1;
094
095   /**
096    * Return code indicating to restart processing the chain from the beginning.
097    */
098   int RESTART = 2;
099
100   /**
101    * Process this response if possible.
102    *
103    * @param opSession The HTTP call.
104    * @return One of the following codes:
105    *    <ul>
106    *       <li><c>0</c> - The processor could not handle the request.
107    *       <li><c>1</c> - The processor was able to fully handle the request.
108    *       <li><c>2</c> - The processor was able to partially handle the request by replacing the output.
109    *          The response processors should start over.
110    *    </ul>
111    * @throws IOException
112    *    If low-level exception occurred on output stream.
113    *    <br>Results in a {@link HttpServletResponse#SC_INTERNAL_SERVER_ERROR} error.
114    * @throws BasicHttpException
115    *    If some other exception occurred.
116    *    <br>Can be used to provide an appropriate HTTP response code and message.
117    */
118   int process(RestOpSession opSession) throws IOException, BasicHttpException;
119}