001/**
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.kernel.modeshape.utils;
017
018import static java.util.Objects.requireNonNull;
019
020import javax.jcr.NamespaceException;
021import javax.jcr.NamespaceRegistry;
022import javax.jcr.RepositoryException;
023import javax.jcr.Session;
024
025import org.fcrepo.kernel.api.exception.FedoraInvalidNamespaceException;
026import org.fcrepo.kernel.api.exception.RepositoryRuntimeException;
027
028/**
029 * Tools for working with the JCR Namespace Registry
030 * @author Benjamin Armintor
031 * @author acoburn
032 * @author ajs6f
033 * @since May 13, 2013
034 */
035public final class NamespaceTools {
036
037    private NamespaceTools() {
038    }
039
040    /**
041     * Return the {@link NamespaceRegistry} associated with the arg session.
042     *
043     * @param session containing the NamespaceRegistry
044     * @return NamespaceRegistry
045     */
046    public static NamespaceRegistry getNamespaceRegistry(final Session session) {
047        try {
048            return requireNonNull(session.getWorkspace().getNamespaceRegistry(),
049                    "Couldn't find namespace registry in repository!");
050        } catch (final RepositoryException e) {
051            throw new RepositoryRuntimeException(e);
052        }
053    }
054
055    /**
056     * Validate resource path for unregistered namespace prefixes
057     *
058     * @param session the JCR session to use
059     * @param path the absolute path to the object
060     * @throws org.fcrepo.kernel.api.exception.FedoraInvalidNamespaceException on unregistered namespaces
061     * @throws org.fcrepo.kernel.api.exception.RepositoryRuntimeException if repository runtime exception occurred
062     */
063    public static void validatePath(final Session session, final String path) {
064
065        final NamespaceRegistry namespaceRegistry = getNamespaceRegistry(session);
066        final String[] pathSegments = path.replaceAll("^/+", "").replaceAll("/+$", "").split("/");
067        for (final String segment : pathSegments) {
068            final int colonPosition = segment.indexOf(':');
069            if (segment.length() > 0 && colonPosition > -1) {
070                final String prefix = segment.substring(0, colonPosition);
071                if (!prefix.equals("fedora")) {
072                    if (prefix.length() == 0) {
073                        throw new FedoraInvalidNamespaceException("Empty namespace in " + segment);
074                    }
075                    try {
076                        namespaceRegistry.getURI(prefix);
077                    } catch (final NamespaceException e) {
078                        throw new FedoraInvalidNamespaceException("Prefix " + prefix + " has not been registered", e);
079                    } catch (final RepositoryException e) {
080                        throw new RepositoryRuntimeException(e);
081                    }
082                }
083            }
084        }
085    }
086}