Package com.esri.gpt.control.arcims

Source Code of com.esri.gpt.control.arcims.ServletConnector

/* 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.control.arcims;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import com.esri.gpt.catalog.arcims.ImsCatalog;
import com.esri.gpt.catalog.arcims.ImsPermissionDao;
import com.esri.gpt.catalog.context.CatalogConfiguration;
import com.esri.gpt.catalog.discovery.DiscoveryException;
import com.esri.gpt.catalog.management.MmdEnums;
import com.esri.gpt.catalog.publication.ProcessingContext;
import com.esri.gpt.catalog.publication.ProcessorFactory;
import com.esri.gpt.catalog.publication.PublicationRequest;
import com.esri.gpt.catalog.publication.ResourceProcessor;
import com.esri.gpt.catalog.schema.ValidationException;
import com.esri.gpt.catalog.search.SearchException;
import com.esri.gpt.framework.context.BaseServlet;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.http.HttpClientRequest;
import com.esri.gpt.framework.jsf.MessageBroker;
import com.esri.gpt.framework.security.credentials.CredentialsDeniedException;
import com.esri.gpt.framework.security.identity.AuthenticationStatus;
import com.esri.gpt.framework.security.identity.IdentityException;
import com.esri.gpt.framework.security.principal.Publisher;
import com.esri.gpt.framework.util.Val;
import com.esri.gpt.framework.xml.XsltTemplate;
import com.esri.gpt.server.csw.provider.components.OperationResponse;
import com.esri.gpt.server.csw.provider.components.RequestHandler;
import com.esri.gpt.server.csw.provider.local.ProviderFactory;

/**
* Servlet Connector for an AtcIMS MetadataServer
*/
public class ServletConnector extends BaseServlet {

// class variables =============================================================
private static final Logger LOGGER = Logger.getLogger(ServletConnector.class
                                 .getName());


// instance variables ==========================================================
/** The GPT TO CSW XSLT template *. */
private XsltTemplate axlToCswXsltTemplate;

/** The GPT TO CSW XSLT template *. */
private XsltTemplate cswToAxlXsltTemplate;

// constructors ================================================================

// properties ==================================================================

// methods =====================================================================

/**
* Handles a GET request.
*
* @param request
*          the servlet request
* @param response
*          the servlet response
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
  getLogger().finer("Query string=" + request.getQueryString());
  if ("ping".equalsIgnoreCase(request.getParameter("Cmd"))) {
    response.getWriter().write("IMS v9.3.0");
  } else if ("ping".equalsIgnoreCase(request.getParameter("cmd"))) {
    response.getWriter().write("IMS v9.3.0");
  } else if ("getVersion".equalsIgnoreCase(request.getParameter("Cmd"))) {
    response.getWriter().write("Version=9.3.0\nBuild_Number=514.2159");
  } else {
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
  }
  // String axlRequest = readInputCharacters(request);
  // getLogger().finer("axlRequest:\n"+axlRequest);
}

/**
* Executes a POST request.
*
* @param request
*          the servlet request
* @param response
*          the servlet response
* @param context
*          the request context
*/
protected void execute(HttpServletRequest request,
    HttpServletResponse response, RequestContext context) throws Exception {

  // initialize
  CatalogConfiguration catConfig = context.getCatalogConfiguration();
  String sService = getServiceName(request);
  String axlRequest = readInputCharacters(request);
  String axlResponse = "";
  String sSourceUri = "";
  String sServiceNameParam = sService;

  if (sService.indexOf(":EB:") != -1) {
    String s[] = sService.split(":EB:");
    sService = s[0];
    sSourceUri = s[1];
  }

  // ensure that a login request was authenticated
  if (sService.toLowerCase().equals("login")) {
    if (!context.getUser().getAuthenticationStatus().getWasAuthenticated()) {
      throw new CredentialsDeniedException("Invalid credentials.");
    }
  }

  boolean proxyMode = true;
 
  // process the request
  getLogger().finest("axlRequest:\n" + axlRequest);
  if (axlRequest.length() > 0) {
    if ((axlRequest.indexOf("<GETCLIENTSERVICES") != -1)) {
      axlResponse = getClientServices(context);
    } else if ((sService.length() > 0) && !sService.toLowerCase().equals("login")) {

      if (sServiceNameParam.indexOf(":EB:") != -1 && axlRequest.indexOf("<PUT_METADATA") != -1) {
          String parts[] = axlRequest.split("<!--");
          String s[] = parts[1].split("-->");
          String xml = s[0];
          if (axlRequest.indexOf("<THUMBNAIL>") != -1 && xml.indexOf("<Thumbnail/>") != -1) {
            xml = setThumbnail(xml, axlRequest);
            axlResponse = publish(context, xml, sSourceUri);
          } else if (xml.indexOf("<gptAgsUrl>") != -1) {
            axlResponse =  handleAgsUrl(context, xml, sSourceUri);
         } else {
          axlResponse = publish(context, xml, sSourceUri);
         }
       }else  if (proxyMode && sServiceNameParam.indexOf(":EB:") == -1){
           axlResponse = makeCswRequestFromAxl(context,request, axlRequest);
      } else {
        throw new Exception("Configuration issue: No ArcXML socket client was created.");
      }
    }
  }

  // write the response
  getLogger().finest("axlResponse:\n" + axlResponse);
  if (axlResponse.length() > 0) {
    writeXmlResponse(response, axlResponse);
  }
}

/**
* Makes csw requests from axl request and return axl response
* @param context the RequestContext
* @param request the HttpServletRequest
* @param axlRequest the axl request
* @return axlResponse the axl response
* @throws SearchException
* @throws TransformerConfigurationException
* @throws TransformerException
* @throws DiscoveryException
*/
public String makeCswRequestFromAxl(RequestContext context,
    HttpServletRequest request, String axlRequest)
    throws SearchException, TransformerConfigurationException,
    TransformerException, DiscoveryException {

  String axlResponse = "";
  if (axlRequest.indexOf("<GET_METADATA><GET_METADATA_DOCUMENT") != -1
      || axlRequest.indexOf("<SEARCH_METADATA") != -1) {

    XsltTemplate template = getAxlToCswXsltTemplate();
    Map<String, String> params = new HashMap<String, String>();
    if (axlRequest.contains("{thisHHHH-isHH-aHHH-dumm-ydocidHHHhhh}")) {
      params.put("all", "all");
    }

    int start = axlRequest.indexOf("startresult=\"");
    int end = 0;
    String parts = null;   
    if(start != -1){
       end = axlRequest.indexOf("\"",start+13);
       parts = axlRequest.substring(start+13,end);
    }
   
    start = axlRequest.indexOf("maxresults=\"");
    String max = null;
    if(start != -1){
       end = axlRequest.indexOf("\"",start+12);
       max =  axlRequest.substring(start+12,end);
    }

    String cswRequest = template.transform(axlRequest, params);
    getLogger().finest(" AXL2CSW transformed request : " + cswRequest);
    String cswResponse = "";
    try {
      RequestHandler handler = ProviderFactory.newHandler(context);
      OperationResponse resp = handler.handleXML(cswRequest);
      cswResponse = resp.getResponseXml();
    } catch (Exception e) {
      throw new SearchException(e);
    }
   
    getLogger().finest(" CSW response : " + cswResponse);
    String metadataUrl = "/csw?service=CSW&request=GetRecordById&version=2.0.2&ElementSetName=full&outputSchema=original&ID=";
    String requestUrl = request.getRequestURL().toString();
    String contextPath = request.getContextPath();
    String baseUrl = requestUrl.substring(0, requestUrl.indexOf(contextPath));
    metadataUrl = baseUrl + contextPath + metadataUrl;
   
    params = new HashMap<String, String>();
    params.put("partialMetadataUrl", metadataUrl);
    params.put("partialThumbnailUrl", baseUrl);
   
    if (axlRequest.indexOf("<GET_METADATA><GET_METADATA_DOCUMENT") != -1) {
      start = axlRequest.indexOf("docid=\"");
      end = axlRequest.indexOf("/></GET_METADATA>");
      String docid = axlRequest.substring(start + 7, end).trim();
      docid = docid.substring(0, docid.length() - 1);
      String url = "/csw?service=CSW&request=GetRecordById&version=2.0.2&ElementSetName=full&outputSchema=original&ID="
          + docid;
      params.put("metadataUrl", url);
    }
   
    if(parts != null && parts.length() > 0){
      params.put("startResult", parts);
    }   
    if(max != null && max.length() > 0){
      params.put("maxResults", max);
    }

    template = getCswToAxlXsltTemplate();   
    axlResponse = template.transform(cswResponse, params);
   
  } else if (axlRequest.indexOf("<GET_METADATA><GET_ROOT_DATASET") != -1) {
    StringBuffer sb = new StringBuffer();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
    .append(
        "<ARCXML version=\"1.1\"><RESPONSE><METADATA numresults=\"17\" startresult=\"0\" total=\"17\">")
    .append(
        "<METADATA_DATASET name=\"Geoportal\" docid=\"{thisHHHH-isHH-aHHH-dumm-ydocidHHHhhh}\" children=\"true\" siblings=\"false\" folder=\"true\" private=\"false\">")
    .append(
        "<ENVELOPE minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90.000000083819\" /></METADATA_DATASET></METADATA></RESPONSE></ARCXML>");
    axlResponse = sb.toString();
  }
  return axlResponse;
}



/**
* Handle Ags url enpoints to publish catalog services
* @param context the RequestContext
* @param xml the xml string
* @param sSourceUri the source Uri
* @return the axl response
* @throws Exception
*/
public String handleAgsUrl(RequestContext context, String xml,
    String sSourceUri) throws Exception {
  String axlResponse = "";

  String url = xml.substring(xml.indexOf("<gptAgsUrl>") + 11,
      xml.indexOf("</gptAgsUrl>")).trim();

  if (url != null && url.length() > 0){
    Publisher publisher = new Publisher(context);
        HttpClientRequest httpClient = HttpClientRequest.newRequest();
        ProcessingContext pContext = new ProcessingContext(context,publisher,httpClient,null,false);
        ProcessorFactory factory = new ProcessorFactory();
        ResourceProcessor processor = factory.interrogate(pContext,url);
        if (processor == null) {
          axlResponse = "Unable to process resource.";
          return axlResponse;
        }
        processor.setPublicationMethod(MmdEnums.PublicationMethod.batch.toString());
        processor.process();
       
        int numCreated = pContext.getNumberCreated();
        int numReplaced = pContext.getNumberReplaced();
        int numFailed = pContext.getNumberFailed();
        int numDeleted = pContext.getNumberDeleted();
        int numUnchanged = pContext.getNumberUnchanged();
   
        StringBuffer sb = new StringBuffer();
      sb
          .append(
              "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ARCXML version=\"1.1\">")
          .append("<RESPONSE><METADATA_ACTION>").append(
              "Publication Summary : ").append(numCreated)
          .append(" created, ").append(numReplaced).append(
              " replaced and ").append(numFailed).append(
              " failed").append(
              "</METADATA_ACTION></RESPONSE></ARCXML>");
      axlResponse = sb.toString();
  } else {
    axlResponse = "Error:ArcGIS Server/Service url is invalid.";
  }
  return axlResponse;
}

/**
* Gets the axl to csw xslt template.
*
* @return the axl to csw xslt template
*
* @throws SearchException
*             the search exception
* @throws Searchception
*             xlst template not initialized by configuration
*/
public XsltTemplate getAxlToCswXsltTemplate() throws SearchException {
  if(this.axlToCswXsltTemplate != null) {
    return this.axlToCswXsltTemplate;
  }  
  String path = "gpt/search/axl2csw.xslt";
  Exception tmpltException = null;
    if(this.axlToCswXsltTemplate != null) {
      return this.axlToCswXsltTemplate;
    }
    try {
      this.axlToCswXsltTemplate = XsltTemplate.makeTemplate(path);
    } catch (TransformerConfigurationException e) {
      tmpltException = e;
    }
  if(tmpltException != null) {
    throw new SearchException("Could not make xslt template from path " +
        path , tmpltException );
  }
   
  return this.axlToCswXsltTemplate;
}

/**
* Gets the axl to csw xslt template.
*
* @return the axl to csw xslt template
*
* @throws SearchException the search exception
* @throws Searchception xlst template not initialized by configuration
*/
public XsltTemplate getCswToAxlXsltTemplate() throws SearchException {
  if(this.cswToAxlXsltTemplate != null) {
    return this.cswToAxlXsltTemplate;
  }
  String path = "gpt/search/csw2axl.xslt";
  Exception tmpltException = null;
    if(this.cswToAxlXsltTemplate != null) {
      return this.cswToAxlXsltTemplate;
    }
    try {
      this.cswToAxlXsltTemplate = XsltTemplate.makeTemplate(path);
    } catch (TransformerConfigurationException e) {
      tmpltException = e;
    }
  if(tmpltException != null) {
    throw new SearchException("Could not make xslt template from path " +
        path , tmpltException );
  }   
  return this.cswToAxlXsltTemplate;
}

/**
* Executes a publish request for GPT publish client tool
*
* @param context
*          the request context
* @param xml
*          the metadata xml string
* @param sourceUri
*          the source uri for metadata document
* @return axlResponse the response message for the publication request
*/
private String publish(RequestContext context, String xml, String sourceUri) {
  String axlResponse = "";
  getLogger().finer("Intercepting publication request...");
  try {

    // prepare the publisher
    Publisher publisher = new Publisher(context);

    // publication request
    PublicationRequest publishRequest = new PublicationRequest(context,
        publisher, xml);
    publishRequest.getPublicationRecord().setSourceFileName(sourceUri);
    publishRequest.getPublicationRecord().setPublicationMethod(
        MmdEnums.PublicationMethod.batch.toString());
    publishRequest.publish();

    boolean bReplaced = publishRequest.getPublicationRecord()
        .getWasDocumentReplaced();
    StringBuffer sb = new StringBuffer();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    sb.append("<ARCXML version=\"1.1\"><RESPONSE><METADATA_ACTION>");
    if (bReplaced) {
      sb.append("REPLACED");
    } else {
      sb.append("OK");
    }
    sb.append("</METADATA_ACTION></RESPONSE></ARCXML>");
    axlResponse = sb.toString();

  } catch (IdentityException e) {
    StringBuffer sb = new StringBuffer();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    sb
        .append("<ARCXML version=\"1.1\"><RESPONSE><ERROR>Error:Authentication failed.</ERROR></RESPONSE></ARCXML>");
    axlResponse = sb.toString();

  } catch (ValidationException e) {
    StringBuffer sb = new StringBuffer();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    sb.append("<ARCXML version=\"1.1\"><RESPONSE><ERROR>");

    boolean bProcessMessages = true;
    if (bProcessMessages) {
      MessageBroker messageBroker = new MessageBroker();
      messageBroker.setBundleBaseName("gpt.resources.gpt");
      ArrayList<String> messages = new ArrayList<String>();
      e.getValidationErrors().buildMessages(messageBroker, messages, true);
      sb.append("ValidationError:Metadata publication failed.");
      boolean bFirst = true;
      for (String error : messages) {
        sb.append("<VALIDATIONERROR><![CDATA[");
        if (bFirst)
          sb.append("(").append(e.getKey()).append(") ");
        sb.append(error).append("]]></VALIDATIONERROR>");
        bFirst = false;
      }
    } else {
      String error = Val.chkStr(e.getMessage());
      sb.append("<![CDATA[ValidationError:Metadata publication failed. "
          + error + "]]>");
    }
    sb.append("</ERROR></RESPONSE></ARCXML>");
    axlResponse = sb.toString();

  } catch (Throwable e) {
    String error = Val.chkStr(e.getMessage());
    StringBuffer sb = new StringBuffer();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    sb.append("<ARCXML version=\"1.1\"><RESPONSE><ERROR>");
    sb.append("<![CDATA[Error:Metadata publication failed. " + error + "]]>");
    sb.append("</ERROR></RESPONSE></ARCXML>");
    axlResponse = sb.toString();
  }
  return axlResponse;
}

/**
* Executes a publish request for GPT publish client tool
*
* @param xml
*          the metadata xml string
* @param axlRequest
*          the ArcXML publish metadata request
* @return newXml the modified metadata xml string
*/
private String setThumbnail(String xml, String axlRequest) {
  String[] parts = axlRequest.split("<THUMBNAIL>");
  String[] s = parts[1].split("</THUMBNAIL>");
  String newXml = xml.replace("<Thumbnail/>",
      "<Thumbnail><Data EsriPropertyType=\"Picture\">" + s[0]
          + "</Data></Thumbnail>");
  return newXml;
}

/**
* Returns the GETCLIENTSERVICES axl.
*
* @param context
*          the request context
* @return the GETCLIENTSERVICES axl
*/
private String getClientServices(RequestContext context) {
  ImsCatalog catalog = context.getCatalogConfiguration().getArcImsCatalog();
  AuthenticationStatus authStatus = context.getUser().getAuthenticationStatus();
  boolean bIsAdministrator = authStatus.getAuthenticatedRoles().hasRole(
      "gptAdministrator");
  boolean bIsPublisher = authStatus.getAuthenticatedRoles().hasRole(
      "gptPublisher");

  StringBuffer sb = new StringBuffer();
  sb.append("<ARCXML version=\"1.0\">\n");
  sb.append("<RESPONSE><SERVICES>");

  String sService = catalog.getBrowseService().getServiceName();
  if (sService.length() > 0) {
    String sRole = "metadata_browser_all";
    sb.append("<SERVICE ACCESS=\"PUBLIC\" DESC=\"\"");
    sb.append(" NAME=\"").append(sService).append("\"");
    sb.append(" SERVICEGROUP=\"MetadataServer1\" STATUS=\"ENABLED\"");
    sb.append(" roles=\"").append(sRole).append("\"");
    sb.append(" TYPE=\"MetadataServer\" VERSION=\"\" group=\"*\">");
    sb.append("<IMAGE TYPE=\"xml,gnd,jpg\"/>");
    sb
        .append("<ENVIRONMENT><LOCALE country=\"US\" language=\"en\" variant=\"\"/><UIFONT name=\"Arial\"/></ENVIRONMENT>");
    sb.append("<CLEANUP INTERVAL=\"10\"/>");
    sb.append("</SERVICE>");
  }

  sService = catalog.getPublishService().getServiceName();
  if ((sService.length() > 0) && (bIsAdministrator || bIsPublisher)) {
    String sRole = ImsPermissionDao.ROLE_PUBLISHER;
    if (bIsAdministrator)
      sRole = ImsPermissionDao.ROLE_ADMINISTRATOR;
    sb.append("<SERVICE ACCESS=\"PUBLIC\" DESC=\"\"");
    sb.append(" NAME=\"").append(sService).append("\"");
    sb.append(" SERVICEGROUP=\"MetadataServer1\" STATUS=\"ENABLED\"");
    sb.append(" roles=\"").append(sRole).append("\"");
    sb.append(" TYPE=\"MetadataServer\" VERSION=\"\" group=\"*\">");
    sb.append("<IMAGE TYPE=\"xml,gnd,jpg\"/>");
    sb
        .append("<ENVIRONMENT><LOCALE country=\"US\" language=\"en\" variant=\"\"/><UIFONT name=\"Arial\"/></ENVIRONMENT>");
    sb.append("<CLEANUP INTERVAL=\"10\"/>");
    sb.append("</SERVICE>");
  }

  sb.append("</SERVICES></RESPONSE></ARCXML>");
  getLogger().finer("GETCLIENTSERVICES response:\n" + sb.toString());
  return sb.toString();
}

/**
* Gets the logger.
*
* @return the logger
*/
@Override
protected Logger getLogger() {
  return LOGGER;
}

/**
* Gets the service name from the servlet request.
*
* @param request
*          the servlet request
* @return the service name
*/
protected String getServiceName(HttpServletRequest request) {
  String sServiceName = "";
  String sQuery = Val.chkStr(request.getQueryString());
  int nIdx = sQuery.toLowerCase().indexOf("servicename=");
  if (nIdx != -1) {
    String sTmp = Val.chkStr(sQuery.substring(nIdx + 12));
    nIdx = sTmp.indexOf("&");
    if (nIdx == -1) {
      sServiceName = sTmp;
    } else if (nIdx > 0) {
      sServiceName = Val.chkStr(sTmp.substring(0, nIdx));
    }
  }
  return sServiceName;
}



}
TOP

Related Classes of com.esri.gpt.control.arcims.ServletConnector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.