SparqlQueryParserCache.java
/*******************************************************************************
* Copyright (c) 2022 Eclipse RDF4J contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
******************************************************************************/
package org.eclipse.rdf4j.sail.shacl.ast;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.eclipse.rdf4j.query.MalformedQueryException;
import org.eclipse.rdf4j.query.QueryLanguage;
import org.eclipse.rdf4j.query.algebra.TupleExpr;
import org.eclipse.rdf4j.query.parser.QueryParser;
import org.eclipse.rdf4j.query.parser.QueryParserFactory;
import org.eclipse.rdf4j.query.parser.QueryParserRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.util.concurrent.UncheckedExecutionException;
public class SparqlQueryParserCache {
private static final Logger logger = LoggerFactory.getLogger(SparqlQueryParserCache.class);
private static final Cache<String, TupleExpr> PARSER_QUERY_CACHE = CacheBuilder.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES)
.concurrencyLevel(Runtime.getRuntime().availableProcessors() * 2)
.maximumSize(10000)
.build();
private static final QueryParser QUERY_PARSER;
static {
Optional<QueryParserFactory> queryParserFactory = QueryParserRegistry.getInstance()
.get(QueryLanguage.SPARQL);
QUERY_PARSER = queryParserFactory
.orElseThrow(() -> new IllegalStateException("Query parser factory for SPARQL is missing!"))
.getParser();
}
public static TupleExpr get(String query) {
try {
return PARSER_QUERY_CACHE.get(query, () -> QUERY_PARSER.parseQuery(query, null).getTupleExpr()).clone();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof MalformedQueryException) {
throw ((MalformedQueryException) e.getCause());
}
if (cause instanceof RuntimeException) {
throw ((RuntimeException) cause);
}
if (cause instanceof Error) {
throw ((Error) cause);
}
if (cause != null) {
throw new IllegalStateException(cause);
}
throw new IllegalStateException(e);
} catch (UncheckedExecutionException e) {
if (e.getCause() instanceof MalformedQueryException) {
logger.error("Error parsing query: \n{}", query, e.getCause());
throw ((MalformedQueryException) e.getCause());
}
throw e;
}
}
}