You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@jena.apache.org by afs <gi...@git.apache.org> on 2018/02/21 14:17:43 UTC

[GitHub] jena pull request #365: JENA-1490: Handle blank nodes client-server when usi...

GitHub user afs opened a pull request:

    https://github.com/apache/jena/pull/365

    JENA-1490: Handle blank nodes client-server when using Fuseki.

    

You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/afs/jena fuseki-connect

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/jena/pull/365.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #365
    
----
commit e4b4f99fe28c68315e08d481e9099c992dd7e0ed
Author: Andy Seaborne <an...@...>
Date:   2018-02-20T13:53:28Z

    JENA-1490: Handle remote blank nodes if remote is Fuseki

commit da71d0f64f2d073429d2732c59d50e5eeb4e30c7
Author: Andy Seaborne <an...@...>
Date:   2018-02-20T13:54:06Z

    Sync for CacheSimple.getOrFill.

commit 0a73699a8c9146b6c163b09abe8b9ee1ece2a766
Author: Andy Seaborne <an...@...>
Date:   2018-02-20T13:54:43Z

    Correct accept content negotiations headers.

commit fc3c3c2c6880cf01da0371885bcac3af413140b5
Author: Andy Seaborne <an...@...>
Date:   2018-02-20T13:55:10Z

    <_:Label> bnodes in SSE.

commit 036491f75dca0ae28b92f99552e354cb03d587c1
Author: Andy Seaborne <an...@...>
Date:   2018-02-20T13:55:25Z

    Better version output.

commit 8aad1f622e3c4a96f33b88f8998ad29531bfdade
Author: Andy Seaborne <an...@...>
Date:   2018-02-20T14:00:51Z

    JENA-1490: Wire in new code

commit 09863b41c2a7cb94d3e507e5f55f8b91b2a64133
Author: Andy Seaborne <an...@...>
Date:   2018-02-20T14:02:38Z

    Interceptor wrapper for RDFConnection

----


---

[GitHub] jena issue #365: JENA-1490: Handle blank nodes client-server when using Fuse...

Posted by afs <gi...@git.apache.org>.
Github user afs commented on the issue:

    https://github.com/apache/jena/pull/365
  
    Add controllable parse-check of SPARQL request strings.



---

[GitHub] jena pull request #365: JENA-1490: Handle blank nodes client-server when usi...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/jena/pull/365


---

[GitHub] jena issue #365: JENA-1490: Handle blank nodes client-server when using Fuse...

Posted by afs <gi...@git.apache.org>.
Github user afs commented on the issue:

    https://github.com/apache/jena/pull/365
  
    Final changes now made.


---

[GitHub] jena pull request #365: JENA-1490: Handle blank nodes client-server when usi...

Posted by rvesse <gi...@git.apache.org>.
Github user rvesse commented on a diff in the pull request:

    https://github.com/apache/jena/pull/365#discussion_r170621100
  
    --- Diff: jena-rdfconnection/src/main/java/org/apache/jena/rdfconnection/RDFConnectionRemoteBuilder.java ---
    @@ -0,0 +1,324 @@
    +/*
    + * 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.apache.jena.rdfconnection;
    +
    +import static java.util.Objects.requireNonNull;
    +
    +import java.util.Objects;
    +import java.util.function.Function;
    +
    +import org.apache.http.client.HttpClient;
    +import org.apache.http.protocol.HttpContext;
    +import org.apache.jena.riot.*;
    +import org.apache.jena.sparql.core.Transactional;
    +import org.apache.jena.sparql.core.TransactionalLock;
    +import org.apache.jena.sparql.engine.http.QueryEngineHTTP;
    +
    +public class RDFConnectionRemoteBuilder {
    +    /*package*/ static String SameAsDestination  = "";
    +
    +    protected Transactional txnLifecycle  = TransactionalLock.createMRPlusSW();
    +    protected HttpClient    httpClient    = null;
    +    protected HttpContext   httpContext   = null;
    +    protected String        destination   = null;
    +    
    +    protected String        sQuery        = SameAsDestination;
    +    protected String        sUpdate       = SameAsDestination;
    +    protected String        sGSP          = SameAsDestination;
    +
    +    protected String        queryURL      = null;
    +    protected String        updateURL     = null;
    +    protected String        gspURL        = null;
    +
    +    // On-the-wire settings.
    +    protected RDFFormat     outputQuads        = RDFFormat.NQUADS;
    +    protected RDFFormat     outputTriples      = RDFFormat.NTRIPLES;
    +    
    +    protected String        acceptGraph        = WebContent.defaultGraphAcceptHeader;
    +    protected String        acceptDataset      = WebContent.defaultDatasetAcceptHeader;
    +    
    +    protected String        acceptSelectResult = QueryEngineHTTP.defaultSelectHeader();
    +    protected String        acceptAskResult    = QueryEngineHTTP.defaultAskHeader();
    +    // All-purpose head that works for any query type (but is quite long!)
    +    protected String        acceptSparqlResults = acceptSelectResult+","+acceptGraph;
    +    // Whether to parse SPARQL Queries and Updates for checkign purposes.
    +    protected boolean       parseCheckQueries   = true;
    +    protected boolean       parseCheckUpdates   = true;
    +
    +    RDFConnectionRemoteBuilder() { 
    +        // Default settings are the meber declarations.
    +    }
    +    
    +    RDFConnectionRemoteBuilder(RDFConnectionRemote base) {
    +        Objects.requireNonNull(base);
    +        txnLifecycle = base.txnLifecycle;
    +        if ( txnLifecycle == null )
    +            txnLifecycle = TransactionalLock.createMRPlusSW();
    +        httpClient          = base.httpClient;
    +        httpContext         = base.httpContext;
    +        destination         = base.destination;
    +        sQuery              = base.svcQuery;
    +        sUpdate             = base.svcUpdate;
    +        sGSP                = base.svcGraphStore;
    +        outputQuads         = base.outputQuads;
    +        outputTriples       = base.outputTriples;
    +        
    +        acceptGraph         = base.acceptGraph;
    +        acceptDataset       = base.acceptDataset;
    +        
    +        acceptSelectResult  = base.acceptSelectResult;
    +        acceptAskResult     = base.acceptAskResult;
    +        parseCheckQueries   = base.parseCheckQueries;
    +        parseCheckUpdates   = base.parseCheckUpdates;
    +    }
    +    
    +    /** URL of the remote SPARQL endpoint.
    +     * For Fuseki, this is the URL of the dataset  e.g. http:/localhost:3030/dataset
    +     */
    +    public RDFConnectionRemoteBuilder destination(String destination) {
    +        Objects.requireNonNull(destination);
    +        this.destination = destination;
    +        return this;
    +    }
    +    
    +    /** Name of the SPARQL query service.
    +     * <p>
    +     * This can be a short name, relative to the destination URL,
    +     * or a full URL (with "http:" or "https:")
    +     * <p>
    +     * Use {@code ""} for "same as destination".
    +     * <br/>
    +     * Use null for "none". 
    +     */
    +    public RDFConnectionRemoteBuilder queryEndpoint(String sQuery) {
    +        this.sQuery = sQuery;
    +        return this;
    +    }
    +    
    +    /** Name of the SPARQL update service.
    +     * <p>
    +     * This can be a short name, relative to the destination URL,
    +     * or a full URL (with "http:" or "https:")
    +     * <p>
    +     * Use {@code ""} for "same as destination".
    +     * <br/>
    +     * Use null for "none". 
    +     */
    +    public RDFConnectionRemoteBuilder updateEndpoint(String sUpdate) {
    +        this.sUpdate = sUpdate;
    +        return this;
    +    }
    +
    +    /** Name of the SPARQL GraphStore Protocol endpoint.
    +     * <p>
    +     * This can be a short name, relative to the destination URL,
    +     * or a full URL (with "http:" or "https:")
    +     * <p>
    +     * Use {@code ""} for "same as destination".
    +     * <br/>
    +     * Use null for "none". 
    +     */
    +    public RDFConnectionRemoteBuilder gspEndpoint(String sGSP) {
    +        this.sGSP = sGSP;
    +        return this;
    +    }
    +    
    +    /** Set the transaction lifecycle. */
    +    /*Future possibility*/
    +    private RDFConnectionRemoteBuilder txnLifecycle(Transactional txnLifecycle) {
    +        this.txnLifecycle = txnLifecycle;
    +        return this;
    +    
    +    }
    +
    +    /** Set the {@link HttpClient} fir the conenction to tbe built */
    +    public RDFConnectionRemoteBuilder httpClient(HttpClient httpClient) {
    +        this.httpClient = httpClient;
    +        return this;
    +    }
    +
    +    /** Set the {@link HttpContext} for the conenction to tbe built */
    +    public RDFConnectionRemoteBuilder httpContext(HttpContext httpContext) {
    +        this.httpContext = httpContext;
    +        return this;
    +    }
    +
    +    /** Set the output format for sending RDF Datasets to the remote server.
    +     * This is used for HTTP PUT and POST to a dataset. 
    +     * This must be a quads format.
    +     */
    +    public RDFConnectionRemoteBuilder quadsFormat(RDFFormat fmtQuads) {
    +        if ( ! RDFLanguages.isQuads(fmtQuads.getLang()) )
    +            throw new RiotException("Not a language for RDF Datasets: "+fmtQuads);
    +        this.outputQuads = fmtQuads;
    +        return this;
    +    }
    +
    +    /** Set the output format for sending RDF Datasets to the remote server.
    +     * This is used for HTTP PUT and POST to a dataset. 
    +     * This must be a quads format.
    +     */
    +    public RDFConnectionRemoteBuilder quadsFormat(Lang langQuads) {
    +        Objects.requireNonNull(langQuads);
    +        if ( ! RDFLanguages.isQuads(langQuads) )
    +            throw new RiotException("Not a language for RDF Datasets: "+langQuads);
    +        RDFFormat fmt = RDFWriterRegistry.defaultSerialization(langQuads);
    +        if ( fmt == null )
    +            throw new RiotException("Language name not recognized: "+langQuads);
    +        quadsFormat(fmt);
    +        return this;
    +    }
    +
    +    /** Set the output format for sending RDF Datasets to the remote server.
    +     * This is used for HTTP PUT and POST to a dataset. 
    +     * This must be a quads format.
    +     */
    +    public RDFConnectionRemoteBuilder quadsFormat(String langQuads) {
    +        Objects.requireNonNull(langQuads);
    +        Lang lang = RDFLanguages.nameToLang(langQuads);
    +        if ( lang == null )
    +            throw new RiotException("Language name not recognized: "+langQuads);
    +        quadsFormat(lang);
    +        return this;
    +    }
    +
    +    /** Set the output format for sending RDF graphs to the remote server. 
    +     * This is used for the SPARQ Graph Store Protocol.
    +     */
    +    public RDFConnectionRemoteBuilder triplesFormat(RDFFormat fmtTriples) {
    +        if ( ! RDFLanguages.isTriples(fmtTriples.getLang()) )
    +            throw new RiotException("Not a language for RDF Graphs: "+fmtTriples);
    +        this.outputTriples = fmtTriples;
    +        return this;
    +    }
    +    
    +    /** Set the output format for sending RDF graphs to the remote server. 
    +     * This is used for the SPARQ Graph Store Protocol.
    +     */
    +    public RDFConnectionRemoteBuilder triplesFormat(Lang langTriples) {
    +        Objects.requireNonNull(langTriples);
    +        if ( ! RDFLanguages.isTriples(langTriples) )
    +            throw new RiotException("Not a language for RDF triples: "+langTriples);
    +        RDFFormat fmt = RDFWriterRegistry.defaultSerialization(langTriples);
    +        if ( fmt == null )
    +            throw new RiotException("Language name not recognized: "+langTriples);
    +        triplesFormat(fmt);
    +        return this;
    +    }
    +
    +    /** Set the output format for sending RDF graphs to the remote server. 
    +     * This is used for the SPARQ Graph Store Protocol.
    +     */
    +    public RDFConnectionRemoteBuilder triplesFormat(String langTriples) {
    +        Objects.requireNonNull(langTriples);
    +        Lang lang = RDFLanguages.nameToLang(langTriples);
    +        if ( lang == null )
    +            throw new RiotException("Language name not recognized: "+langTriples);
    +        quadsFormat(lang);
    +        return this;
    +    }
    +    
    +    /** Set the HTTP {@code Accept:} header used to fetch RDF graph using the SPARQL Graph Store Protocol. */ 
    +    public RDFConnectionRemoteBuilder acceptHeaderGraph(String acceptGraph) {
    +        this.acceptGraph = acceptGraph;
    +        return this;
    +    }
    +    
    +    /** Set the HTTP {@code Accept:} header used to fetch RDF datasets using HTTP GET operations. */ 
    +    public RDFConnectionRemoteBuilder acceptHeaderDataset(String acceptDataset) {
    +        this.acceptDataset = acceptDataset;
    +        return this;
    +    }
    +
    +    /** Set the HTTP {@code Accept:} header used to when making a SPARQL Protocol SELECT query. */ 
    +    public RDFConnectionRemoteBuilder acceptHeaderSelectQuery(String acceptSelectHeader) {
    +        this.acceptSelectResult = acceptSelectHeader;
    +        return this;
    +    }
    +
    +    /** Set the HTTP {@code Accept:} header used to when making a SPARQL Protocol ASK query. */ 
    +    public RDFConnectionRemoteBuilder acceptHeaderAskQuery(String acceptAskHeader) {
    +        this.acceptAskResult = acceptAskHeader;
    +        return this;
    +    }
    +
    +    /** Set the HTTP {@code Accept:} header used to when making a 
    +     * SPARQL Protocol query if no query type specific setting available.
    +     */ 
    +    public RDFConnectionRemoteBuilder acceptHeaderQuery(String acceptHeader) {
    +        this.acceptSparqlResults = acceptHeader;
    +        return this;
    +    }
    +    
    +    /**
    +     * Set the flag for whether to check SPARQL queries and SPARQL updates provided as a string.   
    +     */
    +    public RDFConnectionRemoteBuilder parseCheckSPARQL(boolean parseCheck) {
    +        this.parseCheckQueries = parseCheck;
    +        this.parseCheckUpdates = parseCheck;
    +        return this;
    +    }
    +    
    +    private Function<RDFConnectionRemoteBuilder, RDFConnection> creator = null;
    +    /** Provide an alternative function to make the {@link RDFConnection} object.
    +     * <p>
    +     * Specialized use: This method allows for custom {@code RDFConnection}s.
    +     */
    +    public RDFConnectionRemoteBuilder creator(Function<RDFConnectionRemoteBuilder, RDFConnection> function) {
    +        this.creator = function;
    +        return this;
    +    }
    +
    +    /** Build an {RDFConnection}. */ 
    +    public RDFConnection build() {
    +        requireNonNull(txnLifecycle);
    +        requireNonNull(destination);
    +        
    +        Function<RDFConnectionRemoteBuilder, RDFConnection> maker = creator ;
    +        
    +        if ( maker == null )
    +            maker = (b)->b.buildConnection();
    +        
    +        // Sort out service URLs.
    +        // Delay until here because the order of destination and service settign sisnot
    --- End diff --
    
    Typo - `setting sisnot` -> `settings is not`


---

[GitHub] jena issue #365: JENA-1490: Handle blank nodes client-server when using Fuse...

Posted by afs <gi...@git.apache.org>.
Github user afs commented on the issue:

    https://github.com/apache/jena/pull/365
  
    Note: WIP at this time.
    
    There are tests to be tidied up and put into the PR.



---