| /* |
| * 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.sparql.serializer; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.apache.jena.atlas.io.IndentedWriter; |
| import org.apache.jena.query.QueryVisitor; |
| import org.apache.jena.query.Syntax; |
| import org.apache.jena.riot.system.IRIResolver; |
| import org.apache.jena.sparql.core.Prologue; |
| import org.apache.jena.sparql.modify.request.UpdateSerializer; |
| import org.apache.jena.sparql.modify.request.UpdateWriter; |
| import org.apache.jena.sparql.util.NodeToLabelMapBNode; |
| |
| /** |
| * Provides a registry of serializers for queries and updates |
| * <p> |
| * By registering custom {@link QuerySerializerFactory} or |
| * {@link UpdateSerializerFactory} instances the mapping of a syntax to a |
| * serialization can be customised and this allows the serialization of queries |
| * and updates to be customised if desired. |
| * </p> |
| * <p> |
| * This feature is primarily intended for system programmers as changing how |
| * queries and updates are serialized could have knock on effects particularly |
| * if you use ARQ to interact with remote systems. The default registered |
| * serializers produce standards compliant SPARQL syntax and should be more than |
| * sufficient in most cases |
| * </p> |
| * |
| */ |
| public class SerializerRegistry { |
| |
| private Map<Syntax, QuerySerializerFactory> querySerializers = new HashMap<>(); |
| private Map<Syntax, UpdateSerializerFactory> updateSerializers = new HashMap<>(); |
| |
| private SerializerRegistry() { |
| } |
| |
| private static SerializerRegistry registry; |
| |
| private static synchronized void init() { |
| SerializerRegistry reg = new SerializerRegistry(); |
| |
| // Register standard serializers |
| QuerySerializerFactory arqQuerySerializerFactory = new QuerySerializerFactory() { |
| |
| @Override |
| public QueryVisitor create(Syntax syntax, Prologue prologue, IndentedWriter writer) { |
| // For the query pattern |
| SerializationContext cxt1 = new SerializationContext(prologue, new NodeToLabelMapBNode("b", false)); |
| // For the construct pattern |
| SerializationContext cxt2 = new SerializationContext(prologue, new NodeToLabelMapBNode("c", false)); |
| |
| return new QuerySerializer(writer, new FormatterElement(writer, cxt1), new FmtExprSPARQL(writer, cxt1), |
| new FmtTemplate(writer, cxt2)); |
| } |
| |
| @Override |
| public QueryVisitor create(Syntax syntax, SerializationContext context, IndentedWriter writer) { |
| return new QuerySerializer(writer, new FormatterElement(writer, context), new FmtExprSPARQL(writer, |
| context), new FmtTemplate(writer, context)); |
| } |
| |
| @Override |
| public boolean accept(Syntax syntax) { |
| // Since ARQ syntax is a super set of SPARQL 1.1 both SPARQL 1.0 |
| // and SPARQL 1.1 can be serialized by the same serializer |
| return Syntax.syntaxARQ.equals(syntax) || Syntax.syntaxSPARQL_10.equals(syntax) |
| || Syntax.syntaxSPARQL_11.equals(syntax); |
| } |
| }; |
| reg.addQuerySerializer(Syntax.syntaxARQ, arqQuerySerializerFactory); |
| reg.addQuerySerializer(Syntax.syntaxSPARQL_10, arqQuerySerializerFactory); |
| reg.addQuerySerializer(Syntax.syntaxSPARQL_11, arqQuerySerializerFactory); |
| |
| UpdateSerializerFactory arqUpdateSerializerFactory = new UpdateSerializerFactory() { |
| |
| @Override |
| public UpdateSerializer create(Syntax syntax, Prologue prologue, IndentedWriter writer) { |
| if (!prologue.explicitlySetBaseURI()) |
| prologue = new Prologue(prologue.getPrefixMapping(), (IRIResolver) null); |
| |
| SerializationContext context = new SerializationContext(prologue); |
| return new UpdateWriter(writer, context); |
| } |
| |
| @Override |
| public boolean accept(Syntax syntax) { |
| // Since ARQ syntax is a super set of SPARQL 1.1 both SPARQL 1.0 |
| // and SPARQL 1.1 can be serialized by the same serializer |
| return Syntax.syntaxARQ.equals(syntax) || Syntax.syntaxSPARQL_10.equals(syntax) |
| || Syntax.syntaxSPARQL_11.equals(syntax); |
| } |
| }; |
| reg.addUpdateSerializer(Syntax.syntaxARQ, arqUpdateSerializerFactory); |
| reg.addUpdateSerializer(Syntax.syntaxSPARQL_10, arqUpdateSerializerFactory); |
| reg.addUpdateSerializer(Syntax.syntaxSPARQL_11, arqUpdateSerializerFactory); |
| |
| registry = reg; |
| } |
| |
| /** |
| * Gets the serializer registry which is a singleton lazily instantiating it |
| * if this is the first time this method has been called |
| * |
| * @return Registry |
| */ |
| public static SerializerRegistry get() { |
| if (registry == null) |
| init(); |
| |
| return registry; |
| } |
| |
| /** |
| * Adds a query serializer factory for the given syntax |
| * |
| * @param syntax |
| * Syntax |
| * @param factory |
| * Serializer factory |
| * @throws IllegalArgumentException |
| * Thrown if the given factory does not accept the given syntax |
| */ |
| public void addQuerySerializer(Syntax syntax, QuerySerializerFactory factory) { |
| if (!factory.accept(syntax)) |
| throw new IllegalArgumentException("Factory does not accept the specified syntax"); |
| querySerializers.put(syntax, factory); |
| } |
| |
| /** |
| * Adds an update serializer factory for the given syntax |
| * |
| * @param syntax |
| * Syntax |
| * @param factory |
| * Serializer factory |
| * @throws IllegalArgumentException |
| * Thrown if the given factory does not accept the given syntax |
| */ |
| public void addUpdateSerializer(Syntax syntax, UpdateSerializerFactory factory) { |
| if (!factory.accept(syntax)) |
| throw new IllegalArgumentException("Factory does not accept the specified syntax"); |
| updateSerializers.put(syntax, factory); |
| } |
| |
| /** |
| * Gets whether a query serializer factory is registered for the given |
| * syntax |
| * |
| * @param syntax |
| * Syntax |
| * @return True if registered, false otherwise |
| */ |
| public boolean containsQuerySerializer(Syntax syntax) { |
| return querySerializers.containsKey(syntax) && querySerializers.get(syntax) != null; |
| } |
| |
| /** |
| * Gets whether an update serializer factory is registered for the given |
| * syntax |
| * |
| * @param syntax |
| * Syntax |
| * @return True if registered, false otherwise |
| */ |
| public boolean containsUpdateSerializer(Syntax syntax) { |
| return updateSerializers.containsKey(syntax) && updateSerializers.get(syntax) != null; |
| } |
| |
| /** |
| * Gets the query serializer factory for the given syntax which may be null |
| * if there is none registered |
| * |
| * @param syntax |
| * Syntax |
| * @return Query Serializer Factory or null if none registered for the given |
| * syntax |
| */ |
| public QuerySerializerFactory getQuerySerializerFactory(Syntax syntax) { |
| return querySerializers.get(syntax); |
| } |
| |
| /** |
| * Gets the update serializer factory for the given syntax which may be null |
| * if there is none registered |
| * |
| * @param syntax |
| * Syntax |
| * @return Update Serializer Factory or null if none registered for the |
| * given syntax |
| */ |
| public UpdateSerializerFactory getUpdateSerializerFactory(Syntax syntax) { |
| return updateSerializers.get(syntax); |
| } |
| |
| /** |
| * Removes the query serializer factory for the given syntax |
| * |
| * @param syntax |
| * Syntax |
| */ |
| public void removeQuerySerializer(Syntax syntax) { |
| querySerializers.remove(syntax); |
| } |
| |
| /** |
| * Removes the update serializer factory for the given syntax |
| * |
| * @param syntax |
| * Syntax |
| */ |
| public void removeUpdateSerializer(Syntax syntax) { |
| updateSerializers.remove(syntax); |
| } |
| } |