001 /*
002 * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
003 *
004 * The Apache Software License, Version 1.1
005 *
006 * Redistribution and use in source and binary forms, with or without
007 * modification, are permitted provided that the following conditions
008 * are met:
009 *
010 * 1. Redistributions of source code must retain the above copyright
011 * notice, this list of conditions and the following disclaimer.
012 *
013 * 2. Redistributions in binary form must reproduce the above copyright
014 * notice, this list of conditions and the following disclaimer in
015 * the documentation and/or other materials provided with the
016 * distribution.
017 *
018 * 3. The end-user documentation included with the redistribution, if
019 * any, must include the following acknowlegement:
020 * "This product includes software developed by the
021 * Caucho Technology (http://www.caucho.com/)."
022 * Alternately, this acknowlegement may appear in the software itself,
023 * if and wherever such third-party acknowlegements normally appear.
024 *
025 * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
026 * endorse or promote products derived from this software without prior
027 * written permission. For written permission, please contact
028 * info@caucho.com.
029 *
030 * 5. Products derived from this software may not be called "Resin"
031 * nor may "Resin" appear in their names without prior written
032 * permission of Caucho Technology.
033 *
034 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
036 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
037 * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
038 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
039 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
040 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
041 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
042 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
043 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
044 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
045 *
046 * @author Scott Ferguson
047 */
048
049 package com.caucho.burlap.server;
050
051 import com.caucho.burlap.io.BurlapInput;
052 import com.caucho.burlap.io.BurlapOutput;
053 import com.caucho.services.server.Service;
054 import com.caucho.services.server.ServiceContext;
055
056 import javax.servlet.GenericServlet;
057 import javax.servlet.Servlet;
058 import javax.servlet.ServletConfig;
059 import javax.servlet.ServletException;
060 import javax.servlet.ServletRequest;
061 import javax.servlet.ServletResponse;
062 import javax.servlet.http.HttpServletRequest;
063 import javax.servlet.http.HttpServletResponse;
064 import java.io.IOException;
065 import java.io.InputStream;
066 import java.io.OutputStream;
067 import java.io.PrintWriter;
068
069 /**
070 * Servlet for serving Burlap services.
071 */
072 public class BurlapServlet extends GenericServlet {
073 private Class<?> _apiClass;
074 private Object _service;
075
076 private BurlapSkeleton _skeleton;
077
078 public String getServletInfo()
079 {
080 return "Burlap Servlet";
081 }
082
083 /**
084 * Sets the service class.
085 */
086 public void setService(Object service)
087 {
088 _service = service;
089 }
090
091 /**
092 * Sets the api-class.
093 */
094 public void setAPIClass(Class<?> apiClass)
095 {
096 _apiClass = apiClass;
097 }
098
099 /**
100 * Initialize the service, including the service object.
101 */
102 public void init(ServletConfig config)
103 throws ServletException
104 {
105 super.init(config);
106
107 try {
108 if (_service == null) {
109 String className = getInitParameter("service-class");
110 Class<?> serviceClass = null;
111
112 if (className != null) {
113 ClassLoader loader = Thread.currentThread().getContextClassLoader();
114
115 if (loader != null)
116 serviceClass = Class.forName(className, false, loader);
117 else
118 serviceClass = Class.forName(className);
119 }
120 else {
121 if (getClass().equals(BurlapServlet.class))
122 throw new ServletException("server must extend BurlapServlet");
123
124 serviceClass = getClass();
125 }
126
127 _service = serviceClass.newInstance();
128
129 if (_service instanceof BurlapServlet)
130 ((BurlapServlet) _service).setService(this);
131 if (_service instanceof Service)
132 ((Service) _service).init(getServletConfig());
133 else if (_service instanceof Servlet)
134 ((Servlet) _service).init(getServletConfig());
135 }
136
137 if (_apiClass == null) {
138 String className = getInitParameter("api-class");
139
140 if (className != null) {
141 ClassLoader loader = Thread.currentThread().getContextClassLoader();
142
143 if (loader != null)
144 _apiClass = Class.forName(className, false, loader);
145 else
146 _apiClass = Class.forName(className);
147 }
148 else
149 _apiClass = _service.getClass();
150 }
151
152 _skeleton = new BurlapSkeleton(_service, _apiClass);
153 } catch (ServletException e) {
154 throw e;
155 } catch (Exception e) {
156 throw new ServletException(e);
157 }
158 }
159
160 /**
161 * Execute a request. The path-info of the request selects the bean.
162 * Once the bean's selected, it will be applied.
163 */
164 public void service(ServletRequest request, ServletResponse response)
165 throws IOException, ServletException
166 {
167 HttpServletRequest req = (HttpServletRequest) request;
168 HttpServletResponse res = (HttpServletResponse) response;
169
170 if (! req.getMethod().equals("POST")) {
171 res.setStatus(500, "Burlap Requires POST");
172 PrintWriter out = res.getWriter();
173
174 res.setContentType("text/html");
175 out.println("<h1>Burlap Requires POST</h1>");
176
177 return;
178 }
179
180 String serviceId = req.getPathInfo();
181 String objectId = req.getParameter("id");
182 if (objectId == null)
183 objectId = req.getParameter("ejbid");
184
185 ServiceContext.begin(req, res, serviceId, objectId);
186
187 try {
188 InputStream is = request.getInputStream();
189 OutputStream os = response.getOutputStream();
190
191 BurlapInput in = new BurlapInput(is);
192 BurlapOutput out = new BurlapOutput(os);
193
194 _skeleton.invoke(in, out);
195 } catch (RuntimeException e) {
196 throw e;
197 } catch (ServletException e) {
198 throw e;
199 } catch (Throwable e) {
200 throw new ServletException(e);
201 } finally {
202 ServiceContext.end();
203 }
204 }
205 }