org.springframework.data.semantic.query.AbstractSparqlQuery.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.data.semantic.query.AbstractSparqlQuery.java

Source

/**
 * Copyright (C) 2014 Ontotext AD (info@ontotext.com)
 *
 * Licensed 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.springframework.data.semantic.query;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openrdf.model.URI;
import org.openrdf.query.Binding;
import org.openrdf.query.BindingSet;
import org.openrdf.query.Dataset;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.Query;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.UnsupportedQueryLanguageException;
import org.openrdf.query.algebra.Slice;
import org.openrdf.query.algebra.TupleExpr;
import org.openrdf.query.impl.AbstractQuery;
import org.openrdf.query.impl.DatasetImpl;
import org.openrdf.query.parser.ParsedQuery;
import org.openrdf.query.parser.QueryParserUtil;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sail.SailQuery;
import org.openrdf.repository.sail.SailRepositoryConnection;

public abstract class AbstractSparqlQuery extends AbstractQuery {

    private static final String DISABLE_SAMEAS_URI = "http://www.ontotext.com/disable-sameAs";

    protected String source;
    protected String str;
    private long limit;
    private long offset;
    private boolean sameAs = false;
    private ParsedQuery parsedQuery;

    protected RepositoryConnection connection;

    private Log logger = LogFactory.getLog(AbstractSparqlQuery.class);

    public AbstractSparqlQuery(String source, RepositoryConnection connection)
            throws MalformedQueryException, UnsupportedQueryLanguageException {
        if (source != null && source.length() > 0) {
            this.source = source;
            this.connection = connection;
            str = normalize(source);
            parsedQuery = QueryParserUtil.parseQuery(QueryLanguage.SPARQL, str, null);
            str = removeComments(str);
            dataset = parsedQuery.getDataset();
            TupleExpr expr = parsedQuery.getTupleExpr();
            if (expr instanceof Slice) {
                Slice slice = ((Slice) expr);
                offset = slice.getOffset();
                limit = slice.getLimit();
            } else {
                limit = -1;
            }
        } else {
            throw new MalformedQueryException();
        }
    }

    private String normalize(String source) {
        return source.replaceAll("\\u00a0", " ").replaceAll("\\u00b0", "\t").replaceAll("\\u2028", "\n");
    }

    private String removeComments(String text) {
        return Pattern.compile("^(\\s*)#.*$", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE).matcher(text)
                .replaceAll("");
    }

    private void setSailQueryOffset() {
        SailQuery query = ((SailQuery) getQuery());
        TupleExpr expr = query.getParsedQuery().getTupleExpr();
        Slice slice = null;
        if (expr instanceof Slice) {
            slice = (Slice) expr;
            slice.setOffset(offset);
        } else {
            slice = new Slice(query.getParsedQuery().getTupleExpr(), offset, limit);
        }
        query.getParsedQuery().setTupleExpr(slice);
    }

    private void setSailQueryLimit() {
        SailQuery query = ((SailQuery) getQuery());
        TupleExpr expr = query.getParsedQuery().getTupleExpr();
        Slice slice = null;
        if (expr instanceof Slice) {
            slice = (Slice) expr;
            slice.setLimit(limit);
        } else {
            slice = new Slice(query.getParsedQuery().getTupleExpr(), offset, limit);
        }
        query.getParsedQuery().setTupleExpr(slice);
    }

    private void setHTTPQueryOffset() {
        Pattern p = Pattern.compile("offset \\d+", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(str);
        if (offset > 0 && !m.find()) {
            str = str + " OFFSET " + offset;
        } else {
            str = m.replaceAll(offset > 0 ? "OFFSET " + offset : "");
        }
    }

    private void setHTTPQueryLimit() {
        Pattern p = Pattern.compile("limit\\s+\\d+", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(str);
        if (limit != -1 && !m.find()) {
            str = str + " LIMIT " + limit;
        } else {
            str = m.replaceAll(limit == -1 ? "" : "LIMIT " + limit);
        }
    }

    public void setSameAs(boolean sameAs) {
        this.sameAs = sameAs;
    }

    public boolean isSameAs() {
        return sameAs;
    }

    public void setLimit(long limit) {
        this.limit = limit;
    }

    public long getLimit() {
        return limit;
    }

    public boolean hasLimit() {
        return limit >= 0;
    }

    public void setOffset(long offset) {
        this.offset = offset;
    }

    public long getOffset() {
        return offset;
    }

    public Dataset getDataset() {
        if (getQuery() != null) {
            return getQuery().getDataset();
        }
        return dataset;
    }

    public BindingSet getBindings() {
        if (getQuery() != null) {
            return getQuery().getBindings();
        }
        return super.getBindings();
    }

    public List<String> getBindingNames() {
        if (parsedQuery != null) {
            return new ArrayList<String>(parsedQuery.getTupleExpr().getBindingNames());
        }
        return null;
    }

    public String getSource() {
        return source;
    }

    public String toString() {
        return source;
    }

    protected void prePrepare() {
        if (!(connection instanceof SailRepositoryConnection)) {
            setHTTPQueryOffset();
            setHTTPQueryLimit();
        }
    }

    protected void postPrepare() {

        Query query = getQuery();
        query.setIncludeInferred(includeInferred);
        query.setMaxQueryTime(maxQueryTime);

        for (Binding b : getBindings()) {
            query.setBinding(b.getName(), b.getValue());
        }

        if (dataset != null) {
            if (query.getDataset() == null) {
                query.setDataset(new DatasetImpl());
            }
            for (URI d : dataset.getDefaultGraphs()) {
                ((DatasetImpl) query.getDataset()).addDefaultGraph(d);
            }
            for (URI d : dataset.getNamedGraphs()) {
                ((DatasetImpl) query.getDataset()).addNamedGraph(d);
            }
        }

        if (sameAs) {
            if (query.getDataset() == null) {
                query.setDataset(new DatasetImpl());
            }
            ((DatasetImpl) query.getDataset())
                    .addDefaultGraph(connection.getValueFactory().createURI(DISABLE_SAMEAS_URI));
        }

        if (connection instanceof SailRepositoryConnection) {
            setSailQueryLimit();
            setSailQueryOffset();
        }
    }

    public ParsedQuery getParsedQuery() {
        return parsedQuery;
    }

    protected abstract Query getQuery();

    @Override
    public int hashCode() {
        int hash = (int) (str.hashCode() + offset * 13 + limit * 17);
        if (str.length() > 1) {
            if (sameAs) {
                hash += 31 * str.charAt(0);
            }
            if (includeInferred) {
                hash += 7 * str.charAt(str.length() - 1);
            }
        }
        return hash;
    }

    public boolean equals(Object o) {
        if (o == null) {
            return false;
        } else if (o.getClass().equals(this.getClass())) {
            AbstractSparqlQuery q2 = (AbstractSparqlQuery) o;
            return q2.str.equals(this.str) && (q2.sameAs == this.sameAs)
                    && (q2.includeInferred == this.includeInferred) && (q2.limit == this.limit)
                    && (q2.offset == this.offset);
        } else {
            return false;
        }
    }

    public void close() {
        try {
            connection.close();
        } catch (RepositoryException e) {
            logger.warn(e.getMessage(), e);
        }
    }
}