Package com.esri.gpt.catalog.arcims

Source Code of com.esri.gpt.catalog.arcims.CswRemoteRepository

/* 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.arcims;
import com.esri.gpt.catalog.publication.PublicationRecord;
import com.esri.gpt.catalog.schema.MetadataDocument;
import com.esri.gpt.catalog.schema.Schema;
import com.esri.gpt.framework.collection.StringAttributeMap;
import com.esri.gpt.framework.collection.StringSet;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.util.Val;
import com.esri.gpt.framework.xml.DomUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

/**
* Provides functionality to send metadata document modification events
* (publish/delete) to a remote CSW repository.
*/
class CswRemoteRepository {
 
  /** class variables ========================================================= */
 
  /** The Logger. */
  private static Logger LOGGER = Logger.getLogger(CswRemoteRepository.class.getName());
 
  /** instance variables ====================================================== */
  private String cswURL = "";
  private boolean isActive = false;
  private RequestContext requestContext;
  private StringSet schemaKeys = new StringSet();
  private boolean sendDelete = true;
 
  /** constructors ============================================================ */
 
  /**
   * Constructs with a supplied request context.
   * @param requestContext the active request context
   */
  protected CswRemoteRepository(RequestContext requestContext) {
    this.requestContext = requestContext;
    StringAttributeMap params = requestContext.getCatalogConfiguration().getParameters();
    this.cswURL = Val.chkStr(params.getValue("cswRemoteRepository.url"));
    String sKeys = Val.chkStr(params.getValue("cswRemoteRepository.schemaKeys"));
    String[] aKeys = Val.tokenize(sKeys,",");
    for (String sKey: aKeys) schemaKeys.add(sKey);
    this.isActive = ((cswURL.length() > 0) && (schemaKeys.size() > 0));
    this.sendDelete = Val.chkBool(params.getValue("cswRemoteRepository.sendDelete"),true);
  }
 
  /** methods ================================================================= */
 
  /**
   * Indicates if a remote repository has been configured.
   * @return true if a remote repository has been configured.
   */
  protected boolean isActive() {
    return this.isActive;
  }
 
  /**
   * Deletes a collection of identifiers from the remote repository.
   * @param identifiers the collection of identifiers to delete.
   */
  private void delete(StringSet identifiers) throws IOException {
   
    // make and send the CSW request
    StringBuffer sb = new StringBuffer();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    sb.append("\r\n<csw:Transaction xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\"");
    sb.append(" xmlns:ogc=\"http://www.opengis.net/ogc\">");
    sb.append("\r\n<csw:Delete>");
    sb.append("\r\n<csw:Constraint version=\"1.1.0\">");
    sb.append("\r\n<ogc:Filter>");
    sb.append("\r\n<ogc:Or>");
   
    for (String identifier: identifiers) {
      sb.append("\r\n<ogc:PropertyIsEqualTo>");
      sb.append("\r\n<ogc:PropertyName>").append("dc:identifier").append("</ogc:PropertyName>");
      sb.append("\r\n<ogc:Literal>").append(identifier).append("</ogc:Literal>");
      sb.append("\r\n</ogc:PropertyIsEqualTo>");
    }
  
    sb.append("\r\n</ogc:Or>");
    sb.append("\r\n</ogc:Filter>");
    sb.append("\r\n</csw:Constraint>");
    sb.append("\r\n</csw:Delete>");
    sb.append("\r\n</csw:Transaction>");
    sendRequest(sb.toString());
 
 
  /**
   * Informs the remote repository of record deletions.
   * @param identifiers the file identifiers associated with the deleted records
   */
  protected void onRecordsDeleted(StringSet identifiers) {
    if (!this.isActive() || !this.sendDelete) return;
    try {
      if ((identifiers == null) || (identifiers.size() == 0)) return;
      delete(identifiers);
    } catch (Exception e) {
      LOGGER.log(Level.SEVERE,"Deletion from remote service failed.",e);
    }
  }
 
  /**
   * Informs the remote repository of record publications.
   * @param schema the evaluated schema associated with the document
   * @param record the publication record
   */
  protected void onRecordUpdated(Schema schema, PublicationRecord record) {
    if (!isActive()) return;
    try {
      if (!schemaKeys.containsString(schema.getKey())) return;
      publish(schema,record.getSourceXml());
    } catch (Exception e) {
      LOGGER.log(Level.SEVERE,"Publication to remote service failed.",e);
    }
  }
 
  /**
   * Informs the remote repository of record publications.
   * @param xml the raw XML associated with the record
   * @param record the publication record
   */
  protected void onRecordUpdated(String xml) {
    if (!this.isActive()) return;
    try {
      MetadataDocument mdDoc = new MetadataDocument();
      Schema schema = mdDoc.prepareForView(requestContext,xml);
      xml = mdDoc.prepareForFullViewing(xml);
      publish(schema,xml);
    } catch (Exception e) {
      LOGGER.log(Level.SEVERE,"Publication to remote service failed.",e);
    }
  }
   
  /**
   * Publishes a document to the remote repository.
   * @param schema the evaluated schema associated with the document
   * @param xml the document's XML
   * @throws IOException if an i/o exception occurs
   * @throws ParserConfigurationException if a configuration exception occurs
   * @throws SAXException if an exception occurs during XML parsing
   * @throws TransformerException if an exception occurs during XML transformation
   */
  private void publish(Schema schema, String xml)
    throws IOException, ParserConfigurationException, SAXException, TransformerException {
    if (!schemaKeys.containsString(schema.getKey())) return;
   
    // remove the processing instruction and schema location attribute from the metadata xml
    Document dom = DomUtil.makeDomFromString(xml,true);
    for (int i=0;i<dom.getDocumentElement().getAttributes().getLength();i++) {
      Attr attr = (Attr)dom.getDocumentElement().getAttributes().item(i);
      if (attr.getLocalName().equalsIgnoreCase("schemaLocation")) {
        dom.getDocumentElement().removeAttributeNode(attr);
        break;
      }
    }
    StringWriter result = new StringWriter();
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");
    transformer.transform(new DOMSource(dom),new StreamResult(result));
    xml = Val.chkStr(result.toString());
   
    // make and send the CSW request
    StringBuffer sb = new StringBuffer();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    sb.append("\r\n<csw:Transaction xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\">");
    sb.append("\r\n<csw:Insert>");
    sb.append("\r\n").append(xml);
    sb.append("\r\n</csw:Insert>");
    sb.append("\r\n</csw:Transaction>");
    sendRequest(sb.toString());
  }
 
  /**
   * Fully reads the characters from an InputStream.
   * @param strm the InputStream
   * @return the characters read
   * @throws IOException if an exception occurs
   */
  private StringBuffer readCharacters(InputStream strm)
    throws IOException {
    StringBuffer sb = new StringBuffer();
    BufferedReader br = null;
    InputStreamReader ir = null;
    try {
      char cbuf[] = new char[2048];
      int n = 0;
      int nLen = cbuf.length;
      ir = new InputStreamReader(strm, "UTF-8");
      br = new BufferedReader(ir);
      while ((n = br.read(cbuf, 0, nLen)) > 0) {
        sb.append(cbuf, 0, n);
      }
    } finally {
      try {if (br != null) br.close();} catch (Exception ef) {}
      try {if (ir != null) ir.close();} catch (Exception ef) {}
    }
    return sb;
  }
 
  /**
   * Sends data to the open HTTP connection.
   * @param httpCon the HTTP connection
   * @param data the data to send
   * @throws IOException if the send fails
   */
  private void sendData(HttpURLConnection httpCon, String data)
    throws IOException {
    OutputStream sendStream = null;
    try {
      httpCon.setRequestProperty("Content-Type","text/xml; charset=UTF-8");
      httpCon.setRequestProperty("Content-Length",""+data.length());
      sendStream = httpCon.getOutputStream();
      sendStream.write(data.getBytes("UTF-8"));
      sendStream.flush();
    } finally {
      try {
        if (sendStream != null) {
          sendStream.close();
        }
      } catch (Exception ef) {
      }
    }
  }
 
  /**
   * Sends a request to the CSW end-point.
   * @param cswRequest the request to send
   * @throws IOException if an exception occurs
   */
  private void sendRequest(String cswRequest) throws IOException {
    HttpURLConnection httpCon = null;
    InputStream responseStream = null;
    try {  
      if (LOGGER.isLoggable(Level.FINER)) {
        StringBuffer sb = new StringBuffer();
        sb.append("Sending CSW request\n");
        sb.append(" url=").append(cswURL);
        sb.append("\n").append(cswRequest);
        LOGGER.finer(sb.toString());
      }
     
      //if (true) return;
     
      URL url = new URL(cswURL);
      httpCon = (HttpURLConnection) url.openConnection();
      httpCon.setRequestMethod("POST");
      httpCon.setConnectTimeout(10000);
      httpCon.setDoInput(true);
      httpCon.setDoOutput(true);
      httpCon.setUseCaches(false); // turn off document caching
      httpCon.setRequestProperty("Connection", "Close"); // Disable keep-alive
     
      sendData(httpCon,cswRequest);
      int nResponseCode = httpCon.getResponseCode();
     
      if (LOGGER.isLoggable(Level.FINER)) {
        responseStream = httpCon.getInputStream();
        String sResponse = readCharacters(responseStream).toString()
        StringBuffer sb = new StringBuffer();
        sb.append("Read CSW response\n");
        sb.append(" url=").append(cswURL);
        sb.append(" responseCode=").append(nResponseCode);
        sb.append("\n").append(sResponse);
        LOGGER.finer(sb.toString());
      }
     
    } finally {
      try {if (responseStream != null) responseStream.close();} catch (Exception ef) {}
    }
  }

}
TOP

Related Classes of com.esri.gpt.catalog.arcims.CswRemoteRepository

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.