You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2018/06/12 11:59:12 UTC
[3/5] jena git commit: JENA-1560: PrefixMappingUtils
JENA-1560: PrefixMappingUtils
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/2d74aae7
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/2d74aae7
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/2d74aae7
Branch: refs/heads/master
Commit: 2d74aae7ff954facc801a733fb6cb0eb86ccf86a
Parents: 30d0934
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jun 9 15:38:15 2018 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Jun 12 12:51:12 2018 +0100
----------------------------------------------------------------------
.../apache/jena/util/PrefixMappingUtils.java | 364 +++++++++++++++++++
.../java/org/apache/jena/util/TestPackage.java | 2 +
.../jena/util/TestPrefixMappingUtils.java | 164 +++++++++
3 files changed, 530 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/2d74aae7/jena-core/src/main/java/org/apache/jena/util/PrefixMappingUtils.java
----------------------------------------------------------------------
diff --git a/jena-core/src/main/java/org/apache/jena/util/PrefixMappingUtils.java b/jena-core/src/main/java/org/apache/jena/util/PrefixMappingUtils.java
new file mode 100644
index 0000000..bf3d680
--- /dev/null
+++ b/jena-core/src/main/java/org/apache/jena/util/PrefixMappingUtils.java
@@ -0,0 +1,364 @@
+/*
+ * 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.util;
+
+import java.util.* ;
+import java.util.function.Consumer ;
+import java.util.stream.Collectors ;
+
+import org.apache.jena.atlas.lib.SetUtils ;
+import org.apache.jena.atlas.lib.Trie ;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.graph.Node ;
+import org.apache.jena.graph.Triple ;
+import org.apache.jena.graph.impl.WrappedGraph;
+import org.apache.jena.rdf.model.Model ;
+import org.apache.jena.shared.PrefixMapping ;
+import org.apache.jena.shared.impl.PrefixMappingImpl ;
+
+public class PrefixMappingUtils {
+ /**
+ * Return a read-only graph that has the same data (RDF triples) as the one given, but has a
+ * prefix mapping that only includes "in use" prefixes as calculated by
+ * {@link #calcInUsePrefixMapping(Graph, PrefixMapping)}.
+ * <p>
+ * The prefix mappings of the two graphs are not connected.
+ * Later changes to the prefix mapping of the original graph are not reflected in the returned graph.
+ * Modifications to the triples contained in the underlying graph are reflected.
+ */
+ public static Graph graphInUsePrefixMapping(Graph graph) {
+ final PrefixMapping prefixMapping = calcInUsePrefixMapping(graph) ;
+ prefixMapping.lock() ;
+ Graph graph2 = new WrappedGraph(graph) {
+ @Override
+ public void performAdd(Triple triple)
+ { throw new UnsupportedOperationException() ; }
+
+ @Override
+ public void performDelete(Triple triple)
+ { throw new UnsupportedOperationException() ; }
+
+ @Override
+ public PrefixMapping getPrefixMapping() {
+ return prefixMapping ;
+ }
+ } ;
+ return graph2 ;
+ }
+
+ /**
+ * Analyse the graph to see which prefixes of the graph are in use.
+ * <p>
+ * In the case of overlapping prefixes (where one prefix declaration is has an initial
+ * URI string which matches another prefix declaration), all are included, though
+ * they may not be used when printing (that depends on the output process). In effect,
+ * this process has "false positives".
+ * <p>
+ * This function does not calculate new prefixes.
+ *
+ * @see #calcInUsePrefixMappingTTL(Graph)
+ */
+ public static PrefixMapping calcInUsePrefixMapping(Graph graph) {
+ PrefixMapping prefixMapping = graph.getPrefixMapping() ;
+ if ( prefixMapping == null )
+ return null ;
+ return calcInUsePrefixMapping(graph, prefixMapping) ;
+ }
+
+ /**
+ * Analyse the graph to see which prefixes of the given {@link PrefixMapping} are in
+ * use.
+ * <p>
+ * In the case of overlapping prefixes (where one prefix declaration is has an initial
+ * URI string which matches another prefix declaration), all are included, though
+ * they may not be used when printing (that depends on the output process). In effect,
+ * this process has "false positives".
+ * <p>
+ * This function does not calculate new prefixes.
+ *
+ * @see #calcInUsePrefixMappingTTL(Graph, PrefixMapping)
+ */
+ public static PrefixMapping calcInUsePrefixMapping(Graph graph, PrefixMapping prefixMapping) {
+
+ /* Method:
+ *
+ * For each URI in the data, look it up in the trie.
+ * to see if has a declared prefix.
+ *
+ * Exit early if every prefix is accounted for.
+ */
+
+ // Map prefix to URI.
+ Map<String, String> pmap = prefixMapping.getNsPrefixMap() ;
+
+ // Map URI to prefix, with partial lookup (all uri keys that partly match the URI)
+ Trie<String> trie = new Trie<>() ;
+ // Change this to "add(uri, uri)" to calculate the uris.
+ pmap.forEach((prefix,uri)-> trie.add(uri, prefix)) ;
+ Iterator<Triple> iter = graph.find(null, null, null) ;
+ // Prefixes in use.
+ // (URIs if "add(uri, uri)")
+ Set<String> inUse = new HashSet<>() ;
+
+ // Process to apply to each node
+ // Accumulate any prefixes into 'inUse' if the data URI
+ // is partially matched by a prefix URIs in the trie.
+ Consumer<Node> process = (node)->{
+ if ( ! node.isURI() )
+ return ;
+ String uri = node.getURI() ;
+ // Get all prefixes whose URIs are candidates
+ List<String> hits = trie.partialSearch(uri) ;
+ if ( hits.isEmpty() )
+ return ;
+ inUse.addAll(hits) ;
+ } ;
+
+ while(iter.hasNext()) {
+ Triple triple = iter.next() ;
+ process.accept(triple.getSubject()) ;
+ process.accept(triple.getPredicate()) ;
+ process.accept(triple.getObject()) ;
+ if ( pmap.size() == inUse.size() )
+ break ;
+ }
+
+ if ( pmap.size() == inUse.size() )
+ return prefixMapping ;
+
+ // Build result.
+ PrefixMapping pmap2 = new PrefixMappingImpl() ;
+ inUse.forEach((prefix)-> pmap2.setNsPrefix(prefix, prefixMapping.getNsPrefixURI(prefix)) ) ;
+ return pmap2 ;
+ }
+
+ /**
+ * Analyse the graph to see which prefixes of the graph are in use.
+ * <p>
+ * This function attempts to process each URI in the graph as if it were to be printed
+ * in Turtle. Only prefixes that lead to valid output strings are returned. This is
+ * more expensive than {@link #calcInUsePrefixMapping(Graph)}.
+ * <p>
+ * This function does not calculate new prefixes.
+ *
+ * @see #calcInUsePrefixMappingTTL(Graph)
+ */
+ public static PrefixMapping calcInUsePrefixMappingTTL(Graph graph) {
+ PrefixMapping prefixMapping = graph.getPrefixMapping() ;
+ if ( prefixMapping == null )
+ return null ;
+ return calcInUsePrefixMappingTTL(graph, prefixMapping) ;
+ }
+
+ /**
+ * Analyse the graph to see which prefixes of the given {@link PrefixMapping} are used
+ * by the graph triples.
+ * <p>
+ * This function attempts to process each URI in the graph as if it were to be printed
+ * in Turtle. Only prefixes that lead to valid output strings are returned. This is
+ * more expensive than {@link #calcInUsePrefixMapping(Graph, PrefixMapping)}.
+ * <p>
+ * This function does not calculate new prefixes.
+ *
+ * @see #calcInUsePrefixMapping(Graph, PrefixMapping)
+ */
+ public static PrefixMapping calcInUsePrefixMappingTTL(Graph graph, PrefixMapping prefixMapping) {
+
+ /* Method:
+ *
+ * For each URI, split in in the usual place, after "/" or "#" for http URIs, and
+ * after the last ":" for URNs, then see if that is a declared prefix.
+ *
+ * Exit early if every prefix is accounted for.
+ */
+ // Map prefix -> URI.
+ Map<String, String> pmap = prefixMapping.getNsPrefixMap() ;
+
+ // All URIs used as prefixes in the prefix mapping.
+ Set<String> prefixURIs = new HashSet<>(pmap.values()) ;
+
+ // Prefixes used.
+ Set<String> inUse = new HashSet<>() ;
+ // Process to be applied to each node in the graph.
+ Consumer<Node> process = (node) -> {
+ if ( ! node.isURI() )
+ return ;
+ String uri = node.getURI() ;
+
+ int idx = SplitIRI.splitpoint(uri) ;
+ if ( idx < 0 )
+ return ;
+ String nsURI = SplitIRI.namespaceTTL(uri) ;
+ String prefix = prefixMapping.getNsURIPrefix(nsURI) ;
+ if ( prefix != null )
+ inUse.add(prefix) ;
+ } ;
+
+ Iterator<Triple> iter = graph.find(null, null, null) ;
+ while(iter.hasNext()) {
+ Triple triple = iter.next() ;
+ process.accept(triple.getSubject()) ;
+ process.accept(triple.getPredicate()) ;
+ process.accept(triple.getObject()) ;
+ if ( inUse.size() == prefixURIs.size() )
+ // Fast exit.
+ break ;
+ }
+
+ if ( pmap.size() == inUse.size() )
+ return prefixMapping ;
+
+ // Build result.
+ PrefixMapping pmap2 = new PrefixMappingImpl() ;
+ inUse.forEach((prefix)-> pmap2.setNsPrefix(prefix, prefixMapping.getNsPrefixURI(prefix)) ) ;
+ return pmap2 ;
+ }
+
+ /** Check every URI as a possible use of a prefix */
+ private static Set<String> fullMethod(Model m) {
+ /* Method: Covers prefixes not based on "/", "#" or final ":" splitting.
+ *
+ * Build a trie to use as a partial lookup matcher.
+ * For each URI in the data, look it up as a partial match in the trie
+ * to get all URIs in the prefix map that apply.
+ */
+
+ // Map prefix to URI.
+ Map<String, String> pmap = m.getNsPrefixMap() ;
+ // Map URI to prefix, with partial lookup (all uri keys that partly match the URI)
+ Trie<String> trie = new Trie<>() ;
+
+ // change to add(uri, prefix) to get prefixes.
+ pmap.forEach((prefix,uri)-> trie.add(uri, uri)) ;
+
+ Iterator<Triple> iter = m.getGraph().find(null, null, null) ;
+ // Prefix URIs in use.
+ Set<String> inUseURIs = new HashSet<>() ;
+ while(iter.hasNext()) {
+ Triple triple = iter.next() ;
+ processFull(trie, inUseURIs, triple.getSubject()) ;
+ processFull(trie, inUseURIs, triple.getPredicate()) ;
+ processFull(trie, inUseURIs, triple.getObject()) ;
+ if ( pmap.size() == inUseURIs.size() )
+ break ;
+ }
+ return inUseURIs ;
+ }
+
+ private static void processFull(Trie<String> trie, Set<String> prefixesInUse, Node node) {
+ if ( ! node.isURI() )
+ return ;
+ String uri = node.getURI() ;
+ // Shorten to "/" or "#" or ":"
+ String pref = uri ;
+
+ // Get all under the pref
+ List<String> hits = trie.partialSearch(pref) ;
+ if ( hits == null || hits.isEmpty() )
+ return ;
+ //System.out.println(pref+" => ("+hits.size()+")"+hits) ;
+ prefixesInUse.addAll(hits) ;
+ }
+
+ // -------------------------------------------
+
+ /** Assume that prefixes:localName are in the normal places (after/ or #).
+ * i.e. node.getNameSpace() ; makes sense.
+ * @param m
+ */
+ private static Set<String> splitMethod(Model m) {
+ /* Method:
+ *
+ * For each URI, split in in the usual place, after "/" or "#" for http URIs, and
+ * after the last ":" for URNs, then see if that is a declared prefix.
+ *
+ * Exit early if every prefix is accounted for.
+ */
+
+ PrefixMapping prefixMapping = m ;
+ // Map prefix -> URI.
+ Map<String, String> pmap = prefixMapping.getNsPrefixMap() ;
+
+ // All URIs used as prefixes in the prefix mapping.
+ Set<String> prefixURIs = new HashSet<>(pmap.values()) ;
+
+ // Prefix URIs used.
+ Set<String> inUsePrefixURIs = new HashSet<>() ;
+
+ Iterator<Triple> iter = m.getGraph().find(null, null, null) ;
+ while(iter.hasNext()) {
+ Triple triple = iter.next() ;
+ processBySplit(prefixURIs, inUsePrefixURIs, triple.getSubject()) ;
+ processBySplit(prefixURIs, inUsePrefixURIs, triple.getPredicate()) ;
+ processBySplit(prefixURIs, inUsePrefixURIs, triple.getObject()) ;
+ if ( inUsePrefixURIs.size() == prefixURIs.size() )
+ // Fast exit.
+ break ;
+ }
+ return inUsePrefixURIs ;
+ }
+
+ private static void processBySplit(Collection<String> prefixURIs, Collection<String> inUse, Node node) {
+ if ( ! node.isURI() )
+ return ;
+ String uri = node.getURI() ;
+
+ int idx = SplitIRI.splitpoint(uri) ;
+ if ( idx < 0 )
+ return ;
+ String prefixUri = uri.substring(0,idx) ;
+ String localname = uri.substring(idx) ;
+
+ if ( prefixURIs.contains(prefixUri) )
+ inUse.add(prefixUri) ;
+// String ns = node.getNameSpace() ;
+// if ( ns == null )
+// return ;
+// if ( prefixURIs.contains(ns) )
+// inUse.add(ns) ;
+ }
+
+ // Development assistance in seeing into the algorithms.
+ private static void print(Set<String> inUsePrefixURIs, PrefixMapping prefixMapping) {
+ // Convert to prefixes.
+ Set<String> inUsePrefixes = urisToPrefixes(prefixMapping, inUsePrefixURIs) ;
+ // ----- Analysis
+
+ System.out.println("In use: "+inUsePrefixURIs) ;
+ System.out.println("In use: "+inUsePrefixes) ;
+
+ inUsePrefixURIs.forEach((u)->System.out.printf(" %s: -> <%s>\n", prefixMapping.getNsURIPrefix(u), u)) ;
+
+ // Calc not needed to be efficient.
+ Map<String, String> pmap = prefixMapping.getNsPrefixMap() ;
+ Set<String> prefixURIs = new HashSet<>(pmap.values()) ;
+ Set<String> notInUseURIs = SetUtils.difference(prefixURIs, inUsePrefixURIs) ;
+ Set<String> notInUsePrefixes = SetUtils.difference(pmap.keySet(), inUsePrefixes) ;
+ System.out.println("Not in use: "+notInUseURIs) ;
+ System.out.println("Not in use: "+notInUsePrefixes) ;
+ notInUseURIs.forEach((u)->System.out.printf(" %s: -> <%s>\n", prefixMapping.getNsURIPrefix(u), u)) ;
+ }
+
+ /** Find the prefixes from a set of prefix uri */
+ private static Set<String> urisToPrefixes(PrefixMapping prefixMapping, Set<String> inUsePrefixURIs) {
+ return inUsePrefixURIs.stream()
+ .map(prefixMapping::getNsURIPrefix)
+ .collect(Collectors.toSet()) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/2d74aae7/jena-core/src/test/java/org/apache/jena/util/TestPackage.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/util/TestPackage.java b/jena-core/src/test/java/org/apache/jena/util/TestPackage.java
index bca8337..6e06f53 100644
--- a/jena-core/src/test/java/org/apache/jena/util/TestPackage.java
+++ b/jena-core/src/test/java/org/apache/jena/util/TestPackage.java
@@ -42,10 +42,12 @@ public class TestPackage extends TestSuite {
addTest( "TestFileManager", TestFileManager.suite()) ;
addTest( "TestMonitors", TestMonitors.suite()) ;
addTest( "TestPrintUtil", TestPrintUtil.suite()) ;
+ addTest( "TestPrefixMappingUtils", TestPrefixMappingUtils.suite() );
addTest( TestIteratorCollection.suite() );
addTest( "TestSplitIRI_XML", TestSplitIRI_XML.suite()) ;
addTest( "TestSplitIRI_TTL", TestSplitIRI_TTL.suite()) ;
addTest( "TestModelCollector", TestModelCollector.suite()) ;
+
addTestSuite( TestLocators.class );
addTestSuite( TestOneToManyMap.class );
}
http://git-wip-us.apache.org/repos/asf/jena/blob/2d74aae7/jena-core/src/test/java/org/apache/jena/util/TestPrefixMappingUtils.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/util/TestPrefixMappingUtils.java b/jena-core/src/test/java/org/apache/jena/util/TestPrefixMappingUtils.java
new file mode 100644
index 0000000..5931d5a
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/util/TestPrefixMappingUtils.java
@@ -0,0 +1,164 @@
+/*
+ * 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.util;
+
+import java.io.StringReader ;
+
+import junit.framework.JUnit4TestAdapter;
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.graph.Factory;
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.shared.PrefixMapping ;
+import org.apache.jena.shared.impl.PrefixMappingImpl ;
+import org.junit.Assert ;
+import org.junit.Test ;
+
+public class TestPrefixMappingUtils {
+
+ public static junit.framework.Test suite() {
+ return new JUnit4TestAdapter(TestPrefixMappingUtils.class) ;
+ }
+
+ static Graph create (String data) {
+ Graph graph = Factory.createGraphMem() ;
+ Model m = ModelFactory.createModelForGraph(graph);
+ m.read(new StringReader(data), null, "TTL");
+ return graph ;
+ }
+
+ static int size(PrefixMapping pmap) {
+ return pmap.getNsPrefixMap().size() ;
+ }
+
+ @Test public void prefixes1() {
+ // All prefixes used.
+ String data1 = StrUtils.strjoinNL
+ ("@prefix : <http://example/> ." ,
+ "@prefix ex: <http://example/ex#> ." ,
+ "" ,
+ ":s1 :p :x1 ." ,
+ ":s1 ex:p :x1 ."
+ ) ;
+ Graph graph1 = create(data1) ;
+ PrefixMapping pmap = PrefixMappingUtils.calcInUsePrefixMapping(graph1) ;
+ PrefixMapping pmapExpected = graph1.getPrefixMapping() ;
+ Assert.assertEquals(2, size(pmap)) ;
+ Assert.assertEquals(pmapExpected, pmap) ;
+ }
+
+ @Test public void prefixes2() {
+ // Some prefixes used
+ String data2 = StrUtils.strjoinNL
+ ("@prefix : <http://example/> ." ,
+ "@prefix ex: <http://example/ex#> ." ,
+ "@prefix notinuse: <http://example/whatever/> ." ,
+ "" ,
+ ":s1 :p :x1 ." ,
+ ":s1 ex:p :x1 ."
+ ) ;
+
+ Graph graph1 = create(data2) ;
+ PrefixMapping pmap = PrefixMappingUtils.calcInUsePrefixMapping(graph1) ;
+ PrefixMapping pmapExpected = new PrefixMappingImpl() ;
+ pmapExpected.setNsPrefix("", "http://example/") ;
+ pmapExpected.setNsPrefix("ex", "http://example/ex#") ;
+ Assert.assertEquals(2, size(pmap)) ;
+ Assert.assertTrue(sameMapping(pmapExpected, pmap)) ;
+ Assert.assertTrue(pmap.getNsPrefixURI("notinuse") == null) ;
+ }
+
+ @Test public void prefixes3() {
+ // Some URIs without prefixes.
+ String data = StrUtils.strjoinNL
+ ("@prefix : <http://example/> ." ,
+ "" ,
+ "<http://other/s1> :p :x1 ."
+ ) ;
+ Graph graph1 = create(data) ;
+ PrefixMapping pmap = PrefixMappingUtils.calcInUsePrefixMapping(graph1) ;
+ PrefixMapping pmapExpected = new PrefixMappingImpl() ;
+ pmapExpected.setNsPrefix("", "http://example/") ;
+ Assert.assertTrue(sameMapping(pmapExpected, pmap)) ;
+ }
+
+ @Test public void prefixes4() {
+ // No prefixes.
+ String data = StrUtils.strjoinNL
+ (
+ "<http://other/s1> <http://example/p> 123 ."
+ ) ;
+ Graph graph1 = create(data) ;
+ PrefixMapping pmap = PrefixMappingUtils.calcInUsePrefixMapping(graph1) ;
+ Assert.assertEquals(0, size(pmap)) ;
+ PrefixMapping pmapExpected = new PrefixMappingImpl() ;
+ Assert.assertTrue(sameMapping(pmapExpected, pmap)) ;
+ }
+
+ @Test public void prefixesN() {
+ // All combinations.
+ String data = StrUtils.strjoinNL
+ ("@prefix : <http://example/> ." ,
+ "@prefix ex: <http://example/ex#> ." ,
+ "@prefix notinuse: <http://example/whatever/> ." ,
+ "@prefix indirect: <urn:foo:> ." ,
+ "@prefix indirectx: <urn:x:> ." ,
+
+ "@prefix ns: <http://host/ns> ." ,
+ "@prefix ns1: <http://host/ns1> ." ,
+ "@prefix ns2: <http://host/nspace> ." ,
+ "" ,
+ ":s1 :p :x1 ." ,
+ ":s1 ex:p :x1 ." ,
+
+ "<urn:foo:bar> :p 1 . ",
+ "<urn:x:a:b> :p 2 . ",
+
+ "<urn:verybad#.> :p 1 . ",
+
+ "ns:x ns1:p 'ns1' . ",
+
+ "<http://examp/abberev> indirect:p 'foo' . "
+ ) ;
+
+ Graph graph = create(data) ;
+ PrefixMapping pmap = PrefixMappingUtils.calcInUsePrefixMapping(graph) ;
+ PrefixMapping pmapExpected = new PrefixMappingImpl() ;
+ pmapExpected.setNsPrefix("", "http://example/") ;
+ pmapExpected.setNsPrefix("ex", "http://example/ex#") ;
+ pmapExpected.setNsPrefix("indirect", "urn:foo:") ;
+ pmapExpected.setNsPrefix("ns", "http://host/ns") ;
+ pmapExpected.setNsPrefix("ns1", "http://host/ns1") ;
+ pmapExpected.setNsPrefix("indirectx", "urn:x:") ;
+ //print("Expected:", pmapExpected) ;
+ //print("Got:", pmap) ;
+ Assert.assertTrue(sameMapping(pmapExpected, pmap)) ;
+ Assert.assertTrue(pmap.getNsPrefixURI("notinuse") == null) ;
+ }
+
+ private boolean sameMapping(PrefixMapping pmapExpected, PrefixMapping pmap) {
+ return pmapExpected.samePrefixMappingAs(pmap) ;
+ }
+
+ private static void print(String label, PrefixMapping pmap) {
+ System.out.println(label);
+ pmap.getNsPrefixMap().forEach((p,u)->System.out.printf(" %s: -> <%s>\n", p,u)) ;
+ }
+}