001    package org.apache.turbine.modules.screens;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *   http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import java.io.BufferedReader;
023    import java.io.CharArrayWriter;
024    import java.io.InputStreamReader;
025    import java.io.OutputStreamWriter;
026    import java.io.PrintWriter;
027    
028    import javax.servlet.http.HttpServletRequest;
029    
030    import org.apache.turbine.pipeline.PipelineData;
031    import org.apache.turbine.services.jsonrpc.TurbineJsonRpc;
032    import org.apache.turbine.util.RunData;
033    
034    import com.metaparadigm.jsonrpc.JSONRPCBridge;
035    
036    /**
037     * A Screen class for dealing with JSON-RPC requests.  Typically you would
038     * extend this class and override the doOutput() method to use TurbineJsonRpc
039     * to register the POJOs that will provide the functions you are making
040     * available via JSON-RPC.  Use JSONSecureScreen if you need the user to be
041     * logged in prior to executing the functions you provide.
042     *
043     * <p>Here is an example from a superclass:
044     * <code>
045     * public void doOutput(RunData data) throws Exception
046     * {
047     *     User user = data.getUser();
048     *
049     *     MyJsonFunctions myFunctions = new MyJsonFunctions(user.getName());
050     *
051     *     // Session specific
052     *     TurbineJsonRpc.registerObject(data.getSession(), "myFunctions", myFunctions);
053     *
054     *     // Global
055     *     //TurbineJsonRpc.registerObjectGlobal("testGlobal", testObject);
056     *
057     *     super.doOutput(data);
058     * }
059     * </code>
060     * 
061     * <p>The class MyFunctions would be something like:
062     * <code>
063     * public class MyJsonFunctions
064     * {
065     *     private String getHello(String clientParameter)
066     *     {
067     *         return "Hello " + clientParameter;
068     *     }
069     * }
070     * </code>
071     *
072     * <p>This code is derived from the com.metaparadigm.jsonrpc.JSONRPCServlet
073     *
074     * @author brad@folkens.com
075     * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
076     * @version $Id: JSONScreen.java 958672 2010-06-28 18:42:04Z tv $
077     */
078    public class JSONScreen extends RawScreen
079    {
080        protected static final String JSONRPC_CONTENT_TYPE = "text/plain";
081    
082        protected final static int BUFFER_SIZE = 4096;
083    
084        /**
085         * @see org.apache.turbine.modules.screens.RawScreen#getContentType(org.apache.turbine.util.RunData)
086         * @deprecated Use PipelineData version instead.
087         */
088        protected String getContentType(RunData data)
089        {
090            return JSONRPC_CONTENT_TYPE;
091        }
092    
093        /**
094         * @see org.apache.turbine.modules.screens.RawScreen#getContentType(org.apache.turbine.pipeline.PipelineData)
095         */
096        protected String getContentType(PipelineData pipelineData)
097        {
098            return JSONRPC_CONTENT_TYPE;
099        }
100        
101        /**
102         * @see org.apache.turbine.modules.screens.RawScreen#doOutput(org.apache.turbine.util.RunData)
103         */
104        
105        /**
106         * Output the dynamic content.
107         *
108         * @param data The RunData object.
109         * @deprecated Use PipelineData version instead.
110         */
111        protected void doOutput(RunData data) throws Exception
112        {
113            data.declareDirectResponse();
114            HttpServletRequest request = data.getRequest();
115            
116            //String charset = request.getCharacterEncoding();
117            //if(charset == null)
118            //{
119            //    charset = "UTF-8";
120            //}
121            //BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream(), charset));
122            BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream()));
123    
124            // Read the request
125            CharArrayWriter cdata = new CharArrayWriter();
126            char buf[] = new char[BUFFER_SIZE];
127            int ret;
128            while ((ret = in.read(buf, 0, BUFFER_SIZE)) != -1)
129            {
130                cdata.write(buf, 0, ret);
131            }
132    
133            // Find the JSONRPCBridge for this session or create one
134            // if it doesn't exist
135            JSONRPCBridge json_bridge = TurbineJsonRpc.getBridge(data.getSession());
136    
137            // Process the request
138            Object json_res = TurbineJsonRpc.processCall(cdata, json_bridge, request);
139    
140            PrintWriter out = new PrintWriter(
141                    new OutputStreamWriter(data.getResponse().getOutputStream()));
142            out.print(json_res.toString());
143            out.flush();
144            out.close();
145        }
146    }