org.graphity.core.util.jena.DatasetGraphAccessorHTTP.java Source code

Java tutorial

Introduction

Here is the source code for org.graphity.core.util.jena.DatasetGraphAccessorHTTP.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF 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 org.graphity.core.util.jena;

import org.apache.http.HttpEntity;
import org.apache.http.HttpVersion;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.jena.atlas.web.HttpException;
import org.apache.jena.atlas.web.auth.HttpAuthenticator;
import org.apache.jena.atlas.web.auth.SimpleAuthenticator;
import org.apache.jena.riot.*;
import org.apache.jena.riot.system.IRILib;
import org.apache.jena.riot.web.*;

import com.hp.hpl.jena.Jena;
import com.hp.hpl.jena.graph.Graph;
import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.shared.JenaException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import org.apache.http.entity.InputStreamEntity;
import org.apache.jena.web.DatasetGraphAccessor;
import org.apache.jena.web.HttpSC;

/**
 * A dataset graph accessor that talks to stores that implement the SPARQL 1.1 Graph Store Protocol
 *
 */
public class DatasetGraphAccessorHTTP implements DatasetGraphAccessor {
    // Test for this class are in Fuseki so they can be run with a server. 

    private final String remote;
    private static final HttpResponseHandler noResponse = HttpResponseLib.nullResponse;
    private HttpAuthenticator authenticator;

    /** Format used to send a graph to the server */
    private static RDFFormat sendLang = RDFFormat.NTRIPLES_UTF8; //RDFFormat.RDFXML_PLAIN ;

    /** 
     * Create a DatasetUpdater for the remote URL 
     * @param remote Remote URL
     */
    public DatasetGraphAccessorHTTP(String remote) {
        this.remote = remote;
    }

    /** 
     * Create a DatasetUpdater for the remote URL 
     * @param remote Remote URL
     * @param authenticator HTTP Authenticator
     */
    public DatasetGraphAccessorHTTP(String remote, HttpAuthenticator authenticator) {
        this(remote);
        this.setAuthenticator(authenticator);
    }

    /**
     * Sets authentication credentials for the remote URL
     * @param username User name
     * @param password Password
     */
    public void setAuthentication(String username, char[] password) {
        this.setAuthenticator(new SimpleAuthenticator(username, password));
    }

    /**
     * Sets an authenticator to use for authentication to the remote URL
     * @param authenticator Authenticator
     */
    public void setAuthenticator(HttpAuthenticator authenticator) {
        this.authenticator = authenticator;
    }

    @Override
    public Graph httpGet() {
        return doGet(targetDefault());
    }

    @Override
    public Graph httpGet(Node graphName) {
        return doGet(target(graphName));
    }

    /** Accept header for fetching graphs - prefer N-triples
     * @See WebContent.defaultGraphAcceptHeader 
     *  
     */
    private static String GetAcceptHeader = "application/n-triples,text/turtle;q=0.9,application/rdf+xml;q=0.8,application/xml;q=0.7";

    private Graph doGet(String url) {
        HttpCaptureResponse<Graph> graph = HttpResponseLib.graphHandler();
        try {
            HttpOp.execHttpGet(url, GetAcceptHeader, graph, this.authenticator);
        } catch (HttpException ex) {
            if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
                return null;
            throw ex;
        }
        return graph.get();
    }

    @Override
    public boolean httpHead() {
        return doHead(targetDefault());
    }

    @Override
    public boolean httpHead(Node graphName) {
        return doHead(target(graphName));
    }

    private boolean doHead(String url) {
        HttpUriRequest httpHead = new HttpHead(url);
        try {
            HttpOp.execHttpHead(url, WebContent.defaultGraphAcceptHeader, noResponse, null, null,
                    this.authenticator);
            return true;
        } catch (HttpException ex) {
            if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
                return false;
            throw ex;
        }
    }

    @Override
    public void httpPut(Graph data) {
        doPut(targetDefault(), data);
    }

    @Override
    public void httpPut(Node graphName, Graph data) {
        doPut(target(graphName), data);
    }

    private void doPut(String url, Graph data) {
        HttpEntity entity = graphToHttpEntity(data);
        HttpOp.execHttpPut(url, entity, null, null, this.authenticator);
    }

    @Override
    public void httpDelete() {
        doDelete(targetDefault());
    }

    @Override
    public void httpDelete(Node graphName) {
        doDelete(target(graphName));
    }

    private void doDelete(String url) {
        try {
            HttpOp.execHttpDelete(url, noResponse, null, null, this.authenticator);
        } catch (HttpException ex) {
            if (ex.getResponseCode() == HttpSC.NOT_FOUND_404)
                return;
        }
    }

    @Override
    public void httpPost(Graph data) {
        doPost(targetDefault(), data);
    }

    @Override
    public void httpPost(Node graphName, Graph data) {
        doPost(target(graphName), data);
    }

    private void doPost(String url, Graph data) {
        HttpEntity entity = graphToHttpEntity(data);
        HttpOp.execHttpPost(url, entity, null, null, this.authenticator);
    }

    @Override
    public void httpPatch(Graph data) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void httpPatch(Node graphName, Graph data) {
        throw new UnsupportedOperationException();
    }

    private String targetDefault() {
        return remote + "?" + HttpNames.paramGraphDefault + "=";
    }

    private String target(Node name) {
        if (!name.isURI())
            throw new JenaException("Not a URI: " + name);
        String guri = name.getURI();
        // Encode
        guri = IRILib.encodeUriComponent(guri);
        return remote + "?" + HttpNames.paramGraph + "=" + guri;
    }

    // TODO: Move default parameters into HttpOp and use in ensureClient()

    static private HttpParams httpParams = createHttpParams();

    static private HttpParams createHttpParams() {
        HttpParams httpParams$ = new BasicHttpParams();
        // See DefaultHttpClient.createHttpParams
        HttpProtocolParams.setVersion(httpParams$, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(httpParams$, WebContent.charsetUTF8);
        HttpProtocolParams.setUseExpectContinue(httpParams$, true);
        HttpConnectionParams.setTcpNoDelay(httpParams$, true);
        HttpConnectionParams.setSocketBufferSize(httpParams$, 32 * 1024);
        HttpProtocolParams.setUserAgent(httpParams$, Jena.NAME + "/" + Jena.VERSION);
        return httpParams$;
    }

    private HttpEntity graphToHttpEntity(final Graph graph) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Model model = ModelFactory.createModelForGraph(graph);
        model.write(out, getSendLang().getName()); //model.write(out, WebContent.langNTriples) ;
        byte[] bytes = out.toByteArray();
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        InputStreamEntity reqEntity = new InputStreamEntity(in, bytes.length);
        reqEntity.setContentType(getSendLang().getContentType().getContentType());
        reqEntity.setContentEncoding("UTF-8");
        HttpEntity entity = reqEntity;
        return entity;
        //((HttpEntityEnclosingRequestBase)httpRequest).setEntity(entity) ;

        /*
        ContentProducer producer = new ContentProducer() {
        @Override
        public void writeTo(OutputStream out) throws IOException {
            RDFDataMgr.write(out, graph, sendLang) ;
        }
        } ;
            
        EntityTemplate entity = new EntityTemplate(producer) ;
        String ct = sendLang.getLang().getContentType().getContentType() ;
        entity.setContentType(ct) ;
        return entity ;
        */
    }

    public Lang getSendLang() {
        return sendLang.getLang();
    }

}