Skip to content

Commit

Permalink
Improve error message for cases of invalid or missing namespaces.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedurbin authored and Andrew Woods committed Nov 11, 2014
1 parent 9e12cd3 commit 11bdb14
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 45 deletions.
Expand Up @@ -27,6 +27,7 @@
import static org.fcrepo.kernel.impl.services.TransactionServiceImpl.getCurrentTransactionId;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.getClosestExistingAncestor;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isFrozenNode;
import static org.fcrepo.kernel.utils.NamespaceTools.validatePath;
import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
import static org.slf4j.LoggerFactory.getLogger;
import static org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext;
Expand Down Expand Up @@ -125,6 +126,7 @@ protected FedoraResource doForward(final Resource resource) {
throw new IdentifierConversionException("Asked to translate a resource " + resource
+ " that doesn't match the URI template");
} catch (final RepositoryException e) {
validatePath(session, path);
try {
if ( e instanceof PathNotFoundException ) {
final Node preexistingNode = getClosestExistingAncestor(session, path);
Expand Down
Expand Up @@ -15,20 +15,17 @@
*/
package org.fcrepo.kernel.impl.services;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.fcrepo.kernel.utils.NamespaceTools.validatePath;
import static org.slf4j.LoggerFactory.getLogger;

import java.io.IOException;
import java.io.InputStream;

import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.fcrepo.kernel.models.FedoraResource;
import org.fcrepo.kernel.exception.FedoraInvalidNamespaceException;
import org.fcrepo.kernel.exception.RepositoryRuntimeException;
import org.fcrepo.kernel.impl.FedoraResourceImpl;
import org.fcrepo.kernel.impl.rdf.impl.NodeTypeRdfContext;
Expand Down Expand Up @@ -144,44 +141,6 @@ public void registerNodeTypes(final Session session, final InputStream cndStream
}
}

/**
* Validate resource path for unregistered namespace prefixes
*
* @param session the JCR session to use
* @param path the absolute path to the object
* @throws org.fcrepo.kernel.exception.FedoraInvalidNamespaceException on unregistered namespaces
* @throws RepositoryRuntimeException
*/
private void validatePath(final Session session, final String path) {

final NamespaceRegistry namespaceRegistry;
try {
namespaceRegistry =
session.getWorkspace().getNamespaceRegistry();
checkNotNull(namespaceRegistry,
"Couldn't find namespace registry in repository!");
} catch (final RepositoryException e) {
throw new RepositoryRuntimeException(e);
}

final String relPath = path.replaceAll("^/+", "").replaceAll("/+$", "");
final String[] pathSegments = relPath.split("/");
for (final String segment : pathSegments) {
if (segment.length() > 0 && segment.contains(":") &&
segment.substring(0, segment.indexOf(":")) != "fedora") {
final String prefix = segment.substring(0, segment.indexOf(":"));
try {
namespaceRegistry.getURI(prefix);
} catch (final NamespaceException e) {
throw new FedoraInvalidNamespaceException(
String.format("The namespace prefix (%s) has not been registered", prefix), e);
} catch (final RepositoryException e) {
throw new RepositoryRuntimeException(e);
}
}
}
}

/**
* @param session
* @param path
Expand Down
Expand Up @@ -17,8 +17,13 @@

import static com.google.common.base.Preconditions.checkNotNull;

import javax.jcr.NamespaceException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;

import org.fcrepo.kernel.exception.FedoraInvalidNamespaceException;
import org.fcrepo.kernel.exception.RepositoryRuntimeException;
import org.modeshape.jcr.api.NamespaceRegistry;

import com.google.common.base.Function;
Expand Down Expand Up @@ -47,4 +52,46 @@ public NamespaceRegistry apply(final Node n) {
}

};

/**
* Validate resource path for unregistered namespace prefixes
*
* @param session the JCR session to use
* @param path the absolute path to the object
* @throws org.fcrepo.kernel.exception.FedoraInvalidNamespaceException on unregistered namespaces
* @throws org.fcrepo.kernel.exception.RepositoryRuntimeException
*/
public static void validatePath(final Session session, final String path) {

final javax.jcr.NamespaceRegistry namespaceRegistry;
try {
namespaceRegistry =
session.getWorkspace().getNamespaceRegistry();
checkNotNull(namespaceRegistry,
"Couldn't find namespace registry in repository!");
} catch (final RepositoryException e) {
throw new RepositoryRuntimeException(e);
}

final String relPath = path.replaceAll("^/+", "").replaceAll("/+$", "");
final String[] pathSegments = relPath.split("/");
for (final String segment : pathSegments) {
if (segment.length() > 0 && segment.contains(":") &&
!segment.substring(0, segment.indexOf(":")).equals("fedora")) {
final String prefix = segment.substring(0, segment.indexOf(":"));
if (prefix.length() == 0) {
throw new FedoraInvalidNamespaceException(
String.format("Unable to identify namespace for (%s)", segment));
}
try {
namespaceRegistry.getURI(prefix);
} catch (final NamespaceException e) {
throw new FedoraInvalidNamespaceException(
String.format("The namespace prefix (%s) has not been registered", prefix), e);
} catch (final RepositoryException e) {
throw new RepositoryRuntimeException(e);
}
}
}
}
}
Expand Up @@ -16,17 +16,22 @@
package org.fcrepo.kernel.utils;

import static org.fcrepo.kernel.utils.NamespaceTools.getNamespaceRegistry;
import static org.fcrepo.kernel.utils.NamespaceTools.validatePath;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

import javax.jcr.NamespaceException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;

import org.fcrepo.kernel.exception.FedoraInvalidNamespaceException;
import org.fcrepo.kernel.exception.RepositoryRuntimeException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.modeshape.jcr.api.NamespaceRegistry;

/**
* <p>NamespaceToolsTest class.</p>
Expand All @@ -44,15 +49,56 @@ public class NamespaceToolsTest {
@Mock
private Workspace mockWork;

@Mock
private NamespaceRegistry mockNamespaceRegistry;

@Before
public void setUp() {
public void setUp() throws RepositoryException {
initMocks(this);
when(mockNode.getSession()).thenReturn(mockSession);
when(mockSession.getWorkspace()).thenReturn(mockWork);
}

@Test
public void testFunction() throws RepositoryException {
when(mockNode.getSession()).thenReturn(mockSession);
when(mockSession.getWorkspace()).thenReturn(mockWork);
getNamespaceRegistry.apply(mockNode);
}

@Test (expected = NullPointerException.class)
public void testNullNamespaceRegistry() {
validatePath(mockSession, "irrelevant");
}

@Test (expected = RepositoryRuntimeException.class)
public void testWrapsRepositoryException() {
when(mockSession.getWorkspace()).thenThrow(new RepositoryRuntimeException(""));
validatePath(mockSession, "irrelevant");
}

@Test
public void testValidatePathWithValidNamespace() throws RepositoryException {
when(mockWork.getNamespaceRegistry()).thenReturn(mockNamespaceRegistry);
validatePath(mockSession, "easy/valid:test");
}

@Test (expected = FedoraInvalidNamespaceException.class)
public void testValidatePathWithUnregisteredNamespace() throws RepositoryException {
when(mockWork.getNamespaceRegistry()).thenReturn(mockNamespaceRegistry);
when(mockNamespaceRegistry.getURI("invalid")).thenThrow(new NamespaceException());
validatePath(mockSession, "easy/invalid:test");
}

@Test (expected = FedoraInvalidNamespaceException.class)
public void testValidatePathWithNoNamespace() throws RepositoryException {
when(mockWork.getNamespaceRegistry()).thenReturn(mockNamespaceRegistry);
validatePath(mockSession, "easy/:test");
}

@Test (expected = RepositoryRuntimeException.class)
public void testWrapsRepositoryExceptionFromNamespaceRegistry() throws RepositoryException {
when(mockWork.getNamespaceRegistry()).thenReturn(mockNamespaceRegistry);
when(mockNamespaceRegistry.getURI("broken")).thenThrow(new RepositoryException());
validatePath(mockSession, "test/a/broken:namespace-registry");
}

}

0 comments on commit 11bdb14

Please sign in to comment.