Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -72,22 +72,22 @@ public NamespaceHelper(Session session) {
* @throws RepositoryException if the namespaces could not be retrieved
*/
public Map<String, String> getNamespaces() throws RepositoryException {
Map<String, String> namespaces = new HashMap<String, String>();
Map<String, String> namespaces = new HashMap<>();
String[] prefixes = session.getNamespacePrefixes();
for (String prefixe : prefixes) {
namespaces.put(prefixe, session.getNamespaceURI(prefixe));
for (String prefix : prefixes) {
namespaces.put(prefix, session.getNamespaceURI(prefix));
}
return namespaces;
}

/**
* Returns the prefix mapped to the given namespace URI in the current
* session, or <code>null</code> if the namespace does not exist.
* session, or {@code null} if the namespace does not exist.
*
* @see Session#getNamespacePrefix(String)
* @param uri namespace URI
* @return namespace prefix, or <code>null</code>
* @throws RepositoryException if the namespace could not be retrieved
* @return namespace prefix, or {@code null}
* @throws RepositoryException if the namespace prefix could not be retrieved
*/
public String getPrefix(String uri) throws RepositoryException {
try {
Expand All @@ -99,11 +99,11 @@ public String getPrefix(String uri) throws RepositoryException {

/**
* Returns the namespace URI mapped to the given prefix in the current
* session, or <code>null</code> if the namespace does not exist.
* session, or {@code null} if the namespace does not exist.
*
* @see Session#getNamespaceURI(String)
* @param prefix namespace prefix
* @return namespace prefix, or <code>null</code>
* @return namespace prefix, or {@code null}
* @throws RepositoryException if the namespace could not be retrieved
*/
public String getURI(String prefix) throws RepositoryException {
Expand All @@ -126,7 +126,7 @@ public String getURI(String prefix) throws RepositoryException {
*/
public String getJcrName(String uri, String name)
throws NamespaceException, RepositoryException {
if (uri != null && uri.length() > 0) {
if (uri != null && !uri.isEmpty()) {
return session.getNamespacePrefix(uri) + ":" + name;
} else {
return name;
Expand All @@ -144,6 +144,11 @@ public String getJcrName(String uri, String name)
* <pre>
* node.getProperty(helper.getName("jcr:data"));
* </pre>
* Note that it is simpler to just use the <a href="https://s.apache.org/jcr-2.0-spec/3_Repository_Model.html#3.2.6%20Use%20of%20Qualified%20and%20Expanded%20Names">expanded name</a> wherever supported:
* <pre>
* node.getProperty("http://www.jcp.org/jcr/1.0}data");
* </pre>
* Also note the predefined constants in {@link org.apache.jackrabbit.JcrConstants}.
*
* @param name prefixed name using the standard JCR prefixes
* @return prefixed name using the current session namespace mappings
Expand Down Expand Up @@ -178,7 +183,7 @@ public String getJcrName(String name)
/**
* Safely registers the given namespace. If the namespace already exists,
* then the prefix mapped to the namespace in the current session is
* returned. Otherwise the namespace is registered to the namespace
* returned. Otherwise, the namespace is registered to the namespace
* registry. If the given prefix is already registered for some other
* namespace or otherwise invalid, then another prefix is automatically
* generated. After the namespace has been registered, the prefix mapped
Expand All @@ -199,7 +204,7 @@ public String registerNamespace(String prefix, String uri)
registry.getPrefix(uri);
} catch (NamespaceException e1) {
// Replace troublesome prefix hints
if (prefix == null || prefix.length() == 0
if (prefix == null || prefix.isEmpty()
|| prefix.toLowerCase().startsWith("xml")
|| !XMLChar.isValidNCName(prefix)) {
prefix = "ns"; // ns, ns2, ns3, ns4, ...
Expand Down Expand Up @@ -231,8 +236,7 @@ public String registerNamespace(String prefix, String uri)
* @throws RepositoryException if the namespaces could not be registered
*/
public void registerNamespaces(Map<String,String> namespaces) throws RepositoryException {
for (Map.Entry<String, String> stringStringEntry : namespaces.entrySet()) {
Map.Entry<String, String> entry = stringStringEntry;
for (Map.Entry<String, String> entry : namespaces.entrySet()) {
registerNamespace(entry.getKey(), entry.getValue());
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
/*
* 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.jackrabbit.commons;

import junit.framework.TestCase;
import org.mockito.Mockito;

import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import java.util.HashMap;
import java.util.Map;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

public class NamespaceHelperTest extends TestCase {

private Session session;

@Override
protected void setUp() throws Exception {
super.setUp();
session = Mockito.mock(Session.class);
}

public void testGetNamespaces() throws RepositoryException {
NamespaceHelper nsHelper = new NamespaceHelper(session);

when(session.getNamespacePrefixes()).thenReturn(new String[0]);
Map<String, String> map = nsHelper.getNamespaces();
assertEquals(0, map.size());

when(session.getNamespacePrefixes()).thenReturn(new String[]{"foo"});
map = nsHelper.getNamespaces();
assertEquals(1, map.size());
assertNull(map.get("foo"));

when(session.getNamespacePrefixes()).thenReturn(new String[]{"foo", "bar"});
when(session.getNamespaceURI("bar")).thenReturn("urn:test");
map = nsHelper.getNamespaces();
assertEquals(2, map.size());
assertNull(map.get("foo"));
assertEquals("urn:test", map.get("bar"));
}

public void testGetPrefix() throws RepositoryException {
NamespaceHelper nsHelper = new NamespaceHelper(session);

String uri1 = "urn:test1";

when(session.getNamespacePrefix(uri1)).thenThrow(NamespaceException.class);
String prefix = nsHelper.getPrefix(uri1);
assertNull(prefix);

String uri2 = "urn:test2";

when(session.getNamespacePrefix(uri2)).thenReturn("foo");
prefix = nsHelper.getPrefix(uri2);
assertEquals("foo", prefix);
}

public void testGetURI() throws RepositoryException {
NamespaceHelper nsHelper = new NamespaceHelper(session);

String prefix1 = "prefix1";

when(session.getNamespaceURI(prefix1)).thenThrow(NamespaceException.class);
String uri = nsHelper.getURI(prefix1);
assertNull(uri);

String prefix2 = "prefix2";

when(session.getNamespaceURI(prefix2)).thenReturn("foo:bar");
uri = nsHelper.getURI(prefix2);
assertEquals("foo:bar", uri);
}

public void testGetJcrName() throws RepositoryException {
NamespaceHelper nsHelper = new NamespaceHelper(session);

when(session.getNamespacePrefix(NamespaceHelper.JCR)).thenReturn("jcr");
assertEquals("jcr:xyz", nsHelper.getJcrName("jcr:xyz"));

when(session.getNamespacePrefix(NamespaceHelper.MIX)).thenReturn("foo");
assertEquals("foo:xyz", nsHelper.getJcrName("mix:xyz"));

try {
when(session.getNamespacePrefix("urn:foo")).thenReturn("unknown");
String shouldFail = nsHelper.getJcrName("foo:xyz");
fail("getJcrName should fail for unknown prefix foo, but got: " + shouldFail);
} catch (IllegalArgumentException expected) {
// all good
}

try {
when(session.getNamespacePrefix(NamespaceHelper.NT)).thenThrow(NamespaceException.class);
String shouldFail = nsHelper.getJcrName(NamespaceHelper.NT);
fail("getJcrName should fail for unknown prefix nt, but got: " + shouldFail);
} catch (IllegalArgumentException expected) {
// all good
}
}

public void testGetJcrName2() throws RepositoryException {
NamespaceHelper nsHelper = new NamespaceHelper(session);

assertEquals("foo", nsHelper.getJcrName(null, "foo"));
assertEquals("foo", nsHelper.getJcrName("", "foo"));

when(session.getNamespacePrefix("urn:bar")).thenReturn("bar");
assertEquals("bar:foo", nsHelper.getJcrName("urn:bar", "foo"));
}

public void testRegisterNamespaceAlreadyRegistered() throws RepositoryException {
NamespaceHelper nsHelper = new NamespaceHelper(session);

Workspace workspace = Mockito.mock(Workspace.class);
NamespaceRegistry nsReg = Mockito.mock(NamespaceRegistry.class);

when(session.getWorkspace()).thenReturn(workspace);
when(workspace.getNamespaceRegistry()).thenReturn(nsReg);

when(nsReg.getPrefix("foo:")).thenReturn("xyz");
when(session.getNamespacePrefix("foo:")).thenReturn("xyz");
String prefix = nsHelper.registerNamespace("bar", "foo:");
assertEquals("xyz", prefix);
}

public void testRegisterNamespace() throws RepositoryException {
Workspace workspace = Mockito.mock(Workspace.class);
NamespaceRegistry nsReg = Mockito.mock(NamespaceRegistry.class);

when(session.getWorkspace()).thenReturn(workspace);
when(workspace.getNamespaceRegistry()).thenReturn(nsReg);

// poor man's namespace registry

final HashMap<String, String> pref2uri = new HashMap<>();
final HashMap<String, String> uri2pref = new HashMap<>();

// defaults (incomplete)
pref2uri.put("xml", NamespaceRegistry.NAMESPACE_XML);
uri2pref.put(NamespaceRegistry.NAMESPACE_XML, "xml");
pref2uri.put("jcr", NamespaceRegistry.NAMESPACE_JCR);
uri2pref.put(NamespaceRegistry.NAMESPACE_JCR, "jcr");

Mockito.doAnswer(invocation -> {
String rpref = invocation.getArgument(0);
String ruri = invocation.getArgument(1);
if (null != uri2pref.get(ruri) || null != pref2uri.get(rpref)) {
throw new NamespaceException();
} else {
pref2uri.put(rpref, ruri);
uri2pref.put(ruri, rpref);
return null;
}
}).when(nsReg).registerNamespace(any(), any());

when(nsReg.getPrefix(any())).thenAnswer(invocation -> {
String found = uri2pref.get(invocation.getArgument(0));
if (found != null) {
return found;
} else {
throw new NamespaceException();
}
});

when(nsReg.getURI(any())).thenAnswer(invocation -> {
String found = pref2uri.get(invocation.getArgument(0));
if (found != null) {
return found;
} else {
throw new NamespaceException();
}
});

when(session.getNamespacePrefix(any())).thenAnswer(invocation -> {
String found = uri2pref.get(invocation.getArgument(0));
if (found != null) {
return found;
} else {
throw new NamespaceException();
}
});

when(session.getNamespaceURI(any())).thenAnswer(invocation -> {
String found = pref2uri.get(invocation.getArgument(0));
if (found != null) {
return found;
} else {
throw new NamespaceException();
}
});

NamespaceHelper nsHelper = new NamespaceHelper(session);

// register namespace (test makes assumptions about implementation)

assertEquals("ns", nsHelper.registerNamespace("", "foo:"));
assertEquals("ns2", nsHelper.registerNamespace("", "foo2:"));
assertEquals("ns3", nsHelper.registerNamespace("xmlxxx", "foo3:"));
assertEquals("ns4", nsHelper.registerNamespace("123", "foo4:"));
assertEquals("ns3", nsHelper.registerNamespace("xmlxxx", "foo3:"));
assertEquals("ns5", nsHelper.registerNamespace(null, "foo6:"));

assertEquals("bar", nsHelper.registerNamespace("bar", "bar:"));
assertEquals("bar2", nsHelper.registerNamespace("bar", "bar2:"));
assertEquals("bar3", nsHelper.registerNamespace("bar", "bar3:"));

assertEquals("jcr", nsHelper.registerNamespace("wtf", NamespaceRegistry.NAMESPACE_JCR));
assertEquals("xml", nsHelper.registerNamespace("", NamespaceRegistry.NAMESPACE_XML));

// register namespaces
Map<String, String> input = Map.of("test1", "test1:", "test2", "test2", "", "test3:");
nsHelper.registerNamespaces(input);
assertEquals("test1", nsReg.getPrefix("test1:"));
assertEquals("test2", nsReg.getPrefix("test2"));
assertEquals("ns6", nsReg.getPrefix("test3:"));
}
}