com.esri.gpt.catalog.gxe.GxeServlet.java Source code

Java tutorial

Introduction

Here is the source code for com.esri.gpt.catalog.gxe.GxeServlet.java

Source

/* See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Esri Inc. licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.esri.gpt.catalog.gxe;

import com.esri.gpt.catalog.schema.MetadataDocument;
import com.esri.gpt.catalog.schema.Schema;
import com.esri.gpt.catalog.schema.SchemaException;
import com.esri.gpt.catalog.schema.Schemas;
import com.esri.gpt.catalog.schema.UnrecognizedSchemaException;
import com.esri.gpt.framework.context.BaseServlet;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.jsf.FacesContextBroker;
import com.esri.gpt.framework.jsf.MessageBroker;
import com.esri.gpt.framework.util.Val;
import com.esri.gpt.framework.xml.DomUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.fileupload.FileItem;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
 * The Geoportal XML editor servlet.
 */
@SuppressWarnings("serial")
public class GxeServlet extends BaseServlet {

    /** class variables ========================================================= */

    /** The Logger. */
    private static Logger LOGGER = Logger.getLogger(GxeServlet.class.getName());

    /** methods ================================================================= */

    /**
     * Executes a request.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    @Override
    protected void execute(HttpServletRequest request, HttpServletResponse response, RequestContext context)
            throws Exception {

        // determine the request type and execute
        try {
            if (request.getRequestURI() != null) {
                String sLcUri = request.getRequestURI().toLowerCase();

                if (sLcUri.endsWith("/definition/type")) {
                    this.executeDefinitionType(request, response, context);
                } else if (sLcUri.endsWith("/definition/types")) {
                    this.executeDefinitionTypes(request, response, context);
                } else if (sLcUri.endsWith("/echo/attachment")) {
                    this.executeEchoAttachment(request, response, context);
                } else if (sLcUri.endsWith("/i18n")) {
                    this.executeI18N(request, response, context);
                } else if (sLcUri.endsWith("/interrogate")) {
                    this.executeInterrogate(request, response, context);
                } else if (sLcUri.endsWith("/interrogate/details")) {
                    this.executeInterrogateDetails(request, response, context, true);
                } else if (sLcUri.endsWith("/interrogate/multipart")) {
                    this.executeInterrogate(request, response, context);

                    // this is for backward compatibility, 
                    // should be using /definition/type
                } else if (sLcUri.endsWith("/definition")) {
                    this._executeDefinitionRequest(request, response, context);

                    // this is for backward compatibility, 
                    // should be using /interrogate/details
                } else if (sLcUri.endsWith("/details")) {
                    this.executeInterrogateDetails(request, response, context, false);

                    // this is for backward compatibility, 
                    // should be using /definition/types
                } else if (sLcUri.endsWith("/types")) {
                    this.executeDefinitionTypes(request, response, context);

                }
            }
        } finally {
            context.onExecutionPhaseCompleted();
        }
    }

    /**
     * Handles a request to return the editor definition for
     * a supplied schema key or location.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private void executeDefinitionType(HttpServletRequest request, HttpServletResponse response,
            RequestContext context) throws Exception {

        String sMimeType = "application/json";
        String sResponse = "";
        String sCallback = "";
        MessageBroker msgBroker = null;
        try {

            // determine the response format
            String f = Val.chkStr(request.getParameter("f"));
            if (f.equalsIgnoreCase("pjson")) {
                sMimeType = "text/plain";
            }
            sCallback = Val.chkStr(request.getParameter("callback"));

            // determine the definition
            GxeDefinition definition = null;
            String key = Val.chkStr(request.getParameter("key"));
            String loc = Val.chkStr(request.getParameter("loc"));
            if (key.length() > 0) {
                Schemas schemas = context.getCatalogConfiguration().getConfiguredSchemas();
                Schema schema = schemas.get(key);
                if (schema == null) {
                    throw new SchemaException("Unsupported schema key.");
                } else {
                    definition = schema.getGxeEditorDefinition();
                }
            } else if (loc.length() > 0) {
                definition = new GxeDefinition();
                definition.setFileLocation(loc);
            }
            String sCfg = "";
            if (definition != null) {
                msgBroker = this.getMessageBroker(request, response, context, msgBroker);
                sCfg = this.generateDefinition(request, response, context, msgBroker, definition);
            }

            // set the response
            if ((sCfg != null) && (sCfg.length() > 0)) {
                StringBuilder sb = new StringBuilder();
                sb.append("{");
                sb.append("\r\n\"cfgDefinition\":").append(sCfg);
                sb.append("\r\n}");
                sResponse = sb.toString();
            } else {
                throw new SchemaException("Unsupported schema type.");
            }

        } catch (Throwable t) {
            if (!(t instanceof SchemaException)) {
                LOGGER.log(Level.WARNING, "Error processing request.", t);
            }
            sResponse = this.generateJsonError(request, response, context, msgBroker, t);
        }

        // write the response
        //LOGGER.finest("gxeResponse:\n"+sResponse);
        if ((sResponse != null) && (sResponse.length() > 0)) {
            if ((sCallback != null) && (sCallback.length() > 0)) {
                sResponse = sCallback + "(" + sResponse + ")";
            }
            writeCharacterResponse(response, sResponse, "UTF-8", sMimeType + ";charset=UTF-8");
        }
    }

    /**
     * Handles a request for the list of defined editor types.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private void executeDefinitionTypes(HttpServletRequest request, HttpServletResponse response,
            RequestContext context) throws Exception {

        String sMimeType = "application/json";
        String sResponse = "";
        MessageBroker msgBroker = null;
        try {

            // make the list of defined editor types
            StringBuilder sb = new StringBuilder();
            sb.append("{\"types\": [");
            Schemas schemas = context.getCatalogConfiguration().getConfiguredSchemas();
            if (schemas != null) {
                int n = 0;
                msgBroker = this.getMessageBroker(request, response, context, msgBroker);
                for (Schema schema : schemas.values()) {
                    if (schema.getEditable()) {
                        GxeDefinition definition = schema.getGxeEditorDefinition();
                        if (definition != null) {
                            String key = schema.getKey();
                            String label = null;
                            if (schema.getLabel() != null) {
                                String resKey = schema.getLabel().getResourceKey();
                                if ((resKey != null) && (resKey.length() > 0)) {
                                    label = msgBroker.retrieveMessage(resKey);
                                }
                            }
                            if ((label == null) || (label.length() == 0)) {
                                label = key;
                            }
                            n++;
                            if (n > 1)
                                sb.append(",");
                            sb.append("\r\n\t");
                            sb.append("{\"key\": \"").append(Val.escapeStrForJson(key)).append("\"");
                            sb.append(", \"label\": \"").append(Val.escapeStrForJson(label)).append("\"}");
                        }
                    }
                }
            }
            sb.append("\r\n]}");
            sResponse = sb.toString();

        } catch (Throwable t) {
            LOGGER.log(Level.WARNING, "Error processing request.", t);
            sResponse = this.generateJsonError(request, response, context, msgBroker, t);
        }

        // write the response
        //LOGGER.finest("gxeResponse:\n"+sResponse);
        if ((sResponse != null) && (sResponse.length() > 0)) {
            writeCharacterResponse(response, sResponse, "UTF-8", sMimeType + ";charset=UTF-8");
        }
    }

    /**
     * Handles a request to return a posted XML document as
     * a content disposition attachment.
     * <br/>The posted mime-type should be: application/x-www-form-urlencoded
     * <br/>The posted URL parameter name should be: xml
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private void executeEchoAttachment(HttpServletRequest request, HttpServletResponse response,
            RequestContext context) throws Exception {

        String sResponse = "";
        String sFilename = "";
        try {

            // read the posted xml
            String sXml = this.readPostedXml(request, response, context);
            if ((sXml != null) && (sXml.length() > 0)) {
                sResponse = sXml;
                sFilename = Val.chkStr(request.getParameter("filename"));
                if (sFilename.length() == 0)
                    sFilename = "metadata.xml";
            } else {
                sFilename = "error.txt";
                sResponse = "Error: The posted XML was empty.";
            }
        } catch (Throwable t) {
            LOGGER.log(Level.WARNING, "Error processing request.", t);
            String sMsg = Val.chkStr(t.getMessage());
            if (sMsg.length() == 0)
                sMsg = t.toString();
            sFilename = "error.xml";
            sResponse = "Error: " + sMsg;
        }

        // write the response
        //LOGGER.finest("gxeResponse:\n"+sResponse);
        response.setContentType("APPLICATION/OCTET-STREAM; charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + sFilename + "\"");
        writeCharacterResponse(response, sResponse, "UTF-8", "APPLICATION/OCTET-STREAM; charset=UTF-8");
    }

    /**
     * Handles a request to lookup a set of localized strings.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private void executeI18N(HttpServletRequest request, HttpServletResponse response, RequestContext context)
            throws Exception {

        String sMimeType = "application/json";
        String sResponse = "";
        String sCallback = "";
        MessageBroker msgBroker = null;
        try {

            // determine the response format
            String f = Val.chkStr(request.getParameter("f"));
            if (f.equalsIgnoreCase("pjson")) {
                sMimeType = "text/plain";
            }
            sCallback = Val.chkStr(request.getParameter("callback"));
            msgBroker = this.getMessageBroker(request, response, context, msgBroker);

            // determine the property keys
            String sKeys = Val.chkStr(request.getParameter("keys"));
            String[] aKeys = sKeys.split(",");

            // lookup the strings
            StringBuilder sb = new StringBuilder();
            sb.append("{\"i18n\": {");
            int n = 0;
            if ((aKeys != null) && (aKeys.length > 0)) {
                for (String sKey : aKeys) {
                    String sValue = msgBroker.retrieveMessage(sKey);
                    n++;
                    if (n > 1)
                        sb.append(",");
                    sb.append("\r\n\t");
                    sb.append("\"").append(Val.escapeStrForJson(sKey)).append("\": ");
                    sb.append("\"").append(Val.escapeStrForJson(sValue)).append("\"");
                }
            }
            sb.append("\r\n}}");
            sResponse = sb.toString();

        } catch (Throwable t) {
            LOGGER.log(Level.WARNING, "Error processing request.", t);
            sResponse = this.generateJsonError(request, response, context, msgBroker, t);
        }

        // write the response
        //LOGGER.finest("gxeResponse:\n"+sResponse);
        if ((sResponse != null) && (sResponse.length() > 0)) {
            if ((sCallback != null) && (sCallback.length() > 0)) {
                sMimeType = "text/plain";
                sResponse = sCallback + "(" + sResponse + ")";
            }
            writeCharacterResponse(response, sResponse, "UTF-8", sMimeType + ";charset=UTF-8");
        }
    }

    /**
     * Handles a request to interrogate the editor definition for
     * an uploaded XML document.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private void executeInterrogate(HttpServletRequest request, HttpServletResponse response,
            RequestContext context) throws Exception {

        String sMimeType = "application/json";
        String sResponse = "";
        boolean bWrap = false;
        MessageBroker msgBroker = null;
        try {

            // interrogate the posted XMl, generate the definition
            bWrap = Val.chkBool(request.getParameter("wrap"), false);
            String sXml = this.readPostedXml(request, response, context);
            Schema schema = this.interrogateSchema(context, sXml);
            String sCfg = "";
            GxeDefinition definition = schema.getGxeEditorDefinition();
            if (definition != null) {
                msgBroker = this.getMessageBroker(request, response, context, msgBroker);
                sCfg = this.generateDefinition(request, response, context, msgBroker, definition);
            }

            // set the response
            if ((sCfg != null) && (sCfg.length() > 0)) {
                StringBuilder sb = new StringBuilder();
                sb.append("{");
                sb.append("\r\n\"cfgDefinition\":").append(sCfg);
                sb.append(",\r\n\"xml\":\"").append(Val.escapeStrForJson(schema.getActiveDocumentXml()))
                        .append("\"");
                sb.append("\r\n}");
                sResponse = sb.toString();
            } else {
                throw new SchemaException("Unsupported XML type.");
            }

        } catch (Throwable t) {
            if (!(t instanceof SchemaException)) {
                LOGGER.log(Level.WARNING, "Error processing request.", t);
            }
            sResponse = this.generateJsonError(request, response, context, msgBroker, t);
        }

        // write the response
        //LOGGER.finest("gxeResponse:\n"+sResponse);
        if ((sResponse != null) && (sResponse.length() > 0)) {
            // responseObject= is required for the 
            // HTML5 based dojox.form.Uploader 1.6
            if (bWrap)
                sResponse = "responseObject=" + sResponse;
            writeCharacterResponse(response, sResponse, "UTF-8", sMimeType + ";charset=UTF-8");
        }
    }

    /**
     * Handles a request for a details view of an XML document.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private void executeInterrogateDetails(HttpServletRequest request, HttpServletResponse response,
            RequestContext context, boolean defaultToJson) throws Exception {

        String sMimeType = "application/json";
        String sFormat = "json";
        String sResponse = "";
        MessageBroker msgBroker = null;
        try {

            // determine the response format
            if (!defaultToJson) {
                sFormat = "htmlFragment";
            }
            String f = Val.chkStr(request.getParameter("f"));
            if (f.equalsIgnoreCase("htmlFragment")) {
                sFormat = "htmlFragment";
            } else if (f.equalsIgnoreCase("json")) {
                sFormat = "json";
            } else if (f.equalsIgnoreCase("pjson")) {
                sFormat = "json";
            }
            if (!sFormat.equals("json")) {
                sMimeType = "text/plain";
            }

            // interrogate the posted XMl, generate the details
            String sXml = this.readPostedXml(request, response, context);
            Schema schema = this.interrogateSchema(context, sXml);
            msgBroker = this.getMessageBroker(request, response, context, msgBroker);
            String sDetails = this.generateDetails(request, response, context, msgBroker, schema);
            sDetails = Val.chkStr(sDetails);

            // set the response
            if (sFormat.equals("json")) {
                StringBuilder sb = new StringBuilder();
                sb.append("{");
                sb.append("\"details\": \"").append(Val.escapeStrForJson(sDetails)).append("\"");
                sb.append("}");
                sResponse = sb.toString();
            } else {
                sResponse = sDetails;
            }

        } catch (Throwable t) {
            if (!(t instanceof SchemaException)) {
                LOGGER.log(Level.WARNING, "Error processing request.", t);
            }
            if (sFormat.equals("json")) {
                sResponse = this.generateJsonError(request, response, context, msgBroker, t);
            } else {
                String sMsg = Val.chkStr(t.getMessage());
                if (sMsg.length() == 0)
                    sMsg = t.toString();
                sResponse = Val.escapeXmlForBrowser(sMsg);
            }
        }

        // write the response
        // LOGGER.finest("gxeResponse:\n"+sResponse);
        if ((sResponse != null) && (sResponse.length() > 0)) {
            writeCharacterResponse(response, sResponse, "UTF-8", sMimeType + ";charset=UTF-8");
        }
    }

    /**
     * Generates the JSON editor definition.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @param msgBroker the message broker
     * @param definition the GXE definition
     * @return the JSON definition
     * @throws Exception if a processing exception occurs
     */
    private String generateDefinition(HttpServletRequest request, HttpServletResponse response,
            RequestContext context, MessageBroker msgBroker, GxeDefinition definition) throws Exception {
        GxeContext gxeContext = new GxeContext();
        gxeContext.setMessageBroker(msgBroker);
        if (definition.getRootElement() == null) {
            GxeLoader loader = new GxeLoader();
            loader.loadDefinition(gxeContext, definition);
        }
        GxeJsonSerializer serializer = new GxeJsonSerializer();
        return serializer.asJson(gxeContext, definition);
    }

    /**
     * Generates a details view for an interrogated schema.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @param msgBroker the message broker
     * @param schema the interrogated schema
     * @return the details
     * @throws Exception if a processing exception occurs
     */
    private String generateDetails(HttpServletRequest request, HttpServletResponse response, RequestContext context,
            MessageBroker msgBroker, Schema schema) throws Exception {
        String sXslt = Val.chkStr(schema.getDetailsXslt());
        if (sXslt.length() > 0) {
            MetadataDocument document = new MetadataDocument();
            return document.transformDetails(schema.getActiveDocumentXml(), sXslt, msgBroker);
        }
        return null;
    }

    /**
     * Generates a JSON based error object.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @param msgBroker the message broker
     * @param t the exception
     * @return the JSON string
     */
    private String generateJsonError(HttpServletRequest request, HttpServletResponse response,
            RequestContext context, MessageBroker msgBroker, Throwable t) {
        String sMsg = Val.chkStr(t.getMessage());
        if (sMsg.length() == 0)
            sMsg = t.toString();

        // TODO localized messages here
        if (sMsg.contains("Unrecognized metadata schema.")) {
        } else if (sMsg.contains("Unable to parse document.")) {
        } else if (sMsg.contains("Unsupported XML type.")) {
        }

        StringBuilder sb = new StringBuilder();
        sb.append("{\"error\":{");
        sb.append("\"message\": \"").append(Val.escapeStrForJson(sMsg)).append("\"");
        sb.append("}}");
        return sb.toString();
    }

    /**
     * Ensures the existence of a message broker.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @param msgBroker a message broker reference 
     *   (if null then a new message broker will be generated)
     * @return the message broker
     */
    private MessageBroker getMessageBroker(HttpServletRequest request, HttpServletResponse response,
            RequestContext context, MessageBroker msgBroker) {
        // TODO check for lang parameter
        if (msgBroker != null) {
            return msgBroker;
        } else {
            FacesContextBroker fcb = new FacesContextBroker(request, response);
            return fcb.extractMessageBroker();
        }
    }

    /**
     * Interrogates a schema based upon a posted XML document.
     * @param context the request context
     * @param xml the XML string
     * @return the corresponding schema
     * @throws Exception if a processing exception occurs
     */
    private Schema interrogateSchema(RequestContext context, String xml) throws Exception {
        String sXml = Val.chkStr(Val.removeBOM(xml));
        if (sXml.length() == 0) {
            throw new UnrecognizedSchemaException("Unrecognized metadata schema.");
        } else {
            MetadataDocument document = new MetadataDocument();
            Schema schema = document.prepareForView(context, sXml);
            return schema;
        }
    }

    /**
     * Reads a posted XML document.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private String readPostedXml(HttpServletRequest request, HttpServletResponse response, RequestContext context)
            throws Exception {
        String sXml = "";
        String sContentType = Val.chkStr(request.getContentType());
        if (sContentType.toLowerCase().startsWith("multipart/form-data;")) {
            String sMultipartAttribute = "uploadedfiles[]";
            Object oFile = request.getAttribute(sMultipartAttribute);
            if (oFile == null) {
                sMultipartAttribute = "uploadedfile";
                oFile = request.getAttribute(sMultipartAttribute);
            }
            if ((oFile != null) && (oFile instanceof FileItem)) {
                FileItem item = (FileItem) oFile;
                sXml = Val.chkStr(Val.removeBOM(item.getString("UTF-8")));
            }
        } else if (sContentType.toLowerCase().startsWith("application/x-www-form-urlencoded")) {
            String sFormUrlParamater = "xml";
            sXml = Val.chkStr(Val.removeBOM(request.getParameter(sFormUrlParamater)));
        } else {
            sXml = Val.chkStr(Val.removeBOM(this.readInputCharacters(request)));
        }

        /*
        // check for multipart/form-data
        String sMultipartAttribute = "uploadedfiles[]";
        Object oFile = request.getAttribute(sMultipartAttribute);
        if ((oFile != null) && (oFile instanceof FileItem)) {
          FileItem item = (FileItem)oFile;
          sXml = Val.chkStr(Val.removeBOM(item.getString("UTF-8")));
        } else {
              
          // check for application/x-www-form-urlencoded
          String sFormUrlParamater = "xml";
          sXml = Val.chkStr(request.getParameter(sFormUrlParamater));
          if (sXml == null) {
                
            // check the raw post body
            sXml = this.readInputCharacters(request);
          }
        }
        */
        return sXml;
    }

    /**
     * Handles a request for an editor definition.
     * <br/>Original method, should be deprecated.
     * @param request the HTTP servlet request
     * @param response the HTTP servlet response
     * @param context the request context
     * @throws Exception if a processing exception occurs
     */
    private void _executeDefinitionRequest(HttpServletRequest request, HttpServletResponse response,
            RequestContext context) throws Exception {

        // initialize
        String mimeType = "text/plain";
        String sResponse = "";

        // handle a request for an editor definition
        try {
            GxeContext gxeContext = new GxeContext();
            FacesContextBroker fcb = new FacesContextBroker(request, response);
            gxeContext.setMessageBroker(fcb.extractMessageBroker());

            GxeDefinition definition = null;
            String key = Val.chkStr(request.getParameter("key"));
            String loc = Val.chkStr(request.getParameter("loc"));
            if (key.length() > 0) {
                Schemas schemas = context.getCatalogConfiguration().getConfiguredSchemas();
                Schema schema = schemas.get(key);
                if (schema != null) {
                    definition = schema.getGxeEditorDefinition();
                }
            } else if (loc.length() > 0) {
                definition = new GxeDefinition();
                definition.setFileLocation(loc);
            } else {

                String xml = null;
                try {
                    xml = this.readInputCharacters(request);
                } catch (IOException e) {
                    LOGGER.log(Level.WARNING, "Error processing request.", e);
                    throw new ServletException("400: IOException while reading request body.");
                }
                xml = Val.chkStr(Val.removeBOM(xml));
                if (xml.length() > 0) {
                    MetadataDocument document = new MetadataDocument();
                    Schema schema = document.prepareForView(context, xml);
                    if (schema != null) {
                        definition = schema.getGxeEditorDefinition();
                    }
                }

            }
            if (definition != null) {
                if (definition.getRootElement() == null) {
                    GxeLoader loader = new GxeLoader();
                    loader.loadDefinition(gxeContext, definition);
                }
                GxeJsonSerializer serializer = new GxeJsonSerializer();
                sResponse = serializer.asJson(gxeContext, definition);

                String sCallbackParam = Val.chkStr(request.getParameter("callback"));
                if (sCallbackParam.length() > 0) {
                    sResponse = sCallbackParam + "(" + sResponse + ")";
                }
            }

        } catch (SchemaException e) {
            LOGGER.log(Level.WARNING, "Error processing request.", e);
            String sMsg = e.toString();
            if (sMsg.contains("Unrecognized metadata schema.")) {
                throw new ServletException("409: Unrecognized metadata schema.");
            } else if (sMsg.contains("Unable to parse document.")) {
                throw new ServletException("409: Unable to parse document as XML.");
            } else {
                throw new ServletException("409: Unable process request.");
            }

        } catch (Exception e) {
            throw e;
        } finally {
            context.onExecutionPhaseCompleted();
        }

        // write the response
        LOGGER.finest("gxeResponse:\n" + sResponse);
        if ((sResponse != null) && (sResponse.length() > 0)) {
            writeCharacterResponse(response, sResponse, "UTF-8", mimeType + ";charset=UTF-8");
        }
    }

}