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: *
017: * $Header:$
018: */
019: package org.apache.beehive.netui.pageflow.xmlhttprequest;
020:
021: import org.apache.beehive.netui.core.urls.URLRewriterService;
022: import org.apache.beehive.netui.core.chain.web.WebChainContext;
023: import org.apache.beehive.netui.core.chain.CatalogFactory;
024: import org.apache.beehive.netui.core.chain.Catalog;
025: import org.apache.beehive.netui.core.chain.Command;
026: import org.apache.beehive.netui.core.chain.Context;
027: import org.apache.beehive.netui.core.chain.Chain;
028: import org.apache.beehive.netui.pageflow.interceptor.request.RequestInterceptorContext;
029: import org.apache.beehive.netui.pageflow.interceptor.request.RequestInterceptor;
030: import org.apache.beehive.netui.pageflow.interceptor.Interceptors;
031: import org.apache.beehive.netui.pageflow.interceptor.InterceptorException;
032: import org.apache.beehive.netui.pageflow.interceptor.InterceptorChain;
033: import org.apache.beehive.netui.pageflow.internal.DefaultURLRewriter;
034: import org.apache.beehive.netui.util.logging.Logger;
035: import org.apache.beehive.netui.util.internal.ServletUtils;
036: import org.apache.beehive.netui.util.config.bean.CatalogConfig;
037: import org.apache.beehive.netui.util.config.ConfigUtil;
038:
039: import javax.servlet.http.HttpServlet;
040: import javax.servlet.http.HttpServletResponse;
041: import javax.servlet.http.HttpServletRequest;
042: import javax.servlet.ServletException;
043: import javax.servlet.ServletContext;
044: import java.io.IOException;
045: import java.util.List;
046:
047: /**
048: * Servlet to handle XMLHttpRequests sent from a client.
049: */
050: public class XmlHttpRequestServlet extends HttpServlet {
051: private static final Logger LOG = Logger
052: .getInstance(XmlHttpRequestServlet.class);
053: private static final String COMMAND_XHR = "xhr-commands";
054:
055: public void init() throws ServletException {
056: ServletContext ctxt = getServletContext();
057:
058: /* Initialize the Command chain and add the ErrorCRI */
059:
060: Chain xhrServletCommand = null;
061: CatalogConfig catalogConfig = ConfigUtil.getConfig()
062: .getCatalogConfig();
063: if (catalogConfig != null) {
064: /*
065: todo: neaten up this initialization process. because of the separation between
066: parsing and configuration, this is a second step.
067: Need to put this somewhere in the framework, preferably in a single
068: place that initializes the PageFlow runtime.
069: */
070: CatalogFactory catalogFactory = CatalogFactory
071: .getInstance();
072: if (catalogFactory.getCatalog() == null)
073: catalogFactory = CatalogFactory
074: .getInstance(catalogConfig);
075:
076: assert catalogFactory != null;
077: Catalog catalog = catalogFactory.getCatalog();
078: if (catalog != null) {
079: xhrServletCommand = (Chain) catalog
080: .getCommand(COMMAND_XHR);
081: }
082:
083: if (xhrServletCommand != null) {
084: xhrServletCommand.addCommand(new ErrorCRI());
085: }
086: }
087:
088: /*
089: For compatibility, add the ErrorCRI to the list of global Interceptors only if the
090: Command for the .xhr servlet wasn't found. Note, this code will <em>disappear</em>
091: in a subsequent release of Beehive.
092: */
093: if (xhrServletCommand != null) {
094: RequestInterceptorContext.init(ctxt);
095: RequestInterceptorContext.addInterceptor(ctxt,
096: new ErrorCRI());
097: }
098: }
099:
100: public void doGet(HttpServletRequest request,
101: HttpServletResponse response) throws IOException,
102: ServletException {
103: //System.err.println("Inside the XmlHppRequestServlet:" + request.getRequestURI());
104:
105: // Register the default URLRewriter
106: URLRewriterService.registerURLRewriter(0, request,
107: new DefaultURLRewriter());
108:
109: ServletContext ctxt = getServletContext();
110: Command xhrServletCommand = null;
111: CatalogFactory catalogFactory = CatalogFactory.getInstance();
112: if (catalogFactory != null
113: && catalogFactory.getCatalog() != null) {
114: xhrServletCommand = catalogFactory.getCatalog().getCommand(
115: COMMAND_XHR);
116: }
117:
118: // execute the Command if found or the interceptors if found
119: if (xhrServletCommand != null) {
120: /* todo: add a chain to create the Context object */
121: WebChainContext webChainContext = new WebChainContext(ctxt,
122: request, response);
123:
124: try {
125: xhrServletCommand.execute(webChainContext);
126: } catch (Exception e) {
127: ServletUtils.throwServletException(e);
128: }
129: } else {
130: RequestInterceptorContext context = new RequestInterceptorContext(
131: request, response, ctxt);
132: List interceptors = context.getRequestInterceptors();
133:
134: try {
135: Interceptors.doPreIntercept(context, interceptors);
136: } catch (InterceptorException e) {
137: ServletUtils.throwServletException(e);
138: }
139: }
140:
141: /*
142: Note that we're not worrying about post-intercept or whether any of the pre-interceptors cancelled the
143: request, since there's no further processing in the request.
144: */
145: }
146:
147: public void doPost(HttpServletRequest request,
148: HttpServletResponse response) throws IOException,
149: ServletException {
150: doGet(request, response);
151: }
152:
153: /**
154: * Implementation of a {@link RequestInterceptor} and a {@link Command} that handle errors
155: * sent from the client.
156: *
157: * Note, this class <i>should not</i> be referenced by user code; it is added by the framework.
158: */
159: class ErrorCRI extends RequestInterceptor implements Command {
160: public void preRequest(RequestInterceptorContext ctxt,
161: InterceptorChain chain) throws InterceptorException {
162:
163: HttpServletRequest request = ctxt.getRequest();
164: String cmd = parseCommand(request);
165: render(cmd, request);
166: chain.continueChain();
167: }
168:
169: public void postRequest(RequestInterceptorContext context,
170: InterceptorChain chain) throws InterceptorException {
171: chain.continueChain();
172: }
173:
174: public boolean execute(Context context) throws Exception {
175:
176: assert context != null;
177: assert context instanceof WebChainContext;
178: assert ((WebChainContext) context).getServletRequest() instanceof HttpServletRequest;
179: assert ((WebChainContext) context).getServletResponse() instanceof HttpServletResponse;
180:
181: WebChainContext webChainContext = (WebChainContext) context;
182: HttpServletRequest request = (HttpServletRequest) webChainContext
183: .getServletRequest();
184:
185: String cmd = parseCommand(request);
186: return render(cmd, request);
187: }
188:
189: private String parseCommand(HttpServletRequest request) {
190: // Create the command by striping off the context path and the extension
191: String cmd = request.getRequestURI();
192: String ctxtPath = request.getContextPath();
193:
194: // catch any runtime errors here and return.
195: try {
196: cmd = cmd.substring(ctxtPath.length() + 1);
197: int idx = cmd.lastIndexOf('.');
198: if (idx != -1) {
199: cmd = cmd.substring(0, idx);
200: }
201: } catch (RuntimeException e) {
202: LOG.error(
203: "Runtime Error creating XmlRequestServlet Command:"
204: + e.getClass().getName(), e);
205:
206: // set the command string to null to prevent the ErrorCRI command handler from executing
207: cmd = null;
208: }
209:
210: return cmd;
211: }
212:
213: private boolean render(String cmd, HttpServletRequest request) {
214: try {
215: if ("netuiError".equals(cmd)) {
216: String error = request.getParameter("error");
217: LOG.error("NetUI JavaScript Error:" + error);
218: //System.err.println("NetUI JavaScript Error:" + error);
219: return true;
220: }
221: } catch (RuntimeException e) {
222: LOG.error(
223: "Runtime Error creating XmlRequestServlet Command:"
224: + e.getClass().getName(), e);
225: }
226:
227: /*
228: If the command wasn't a "netuiError", don't assume that it was handled and let
229: any additional Commands have a chance to take some action in response to
230: an error.
231: */
232: return false;
233: }
234:
235: }
236: }
|