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.api.utils; 017 018import java.util.Objects; 019import java.util.function.Function; 020 021import javax.jcr.NamespaceException; 022import javax.jcr.Node; 023import javax.jcr.RepositoryException; 024import javax.jcr.Session; 025 026import org.fcrepo.kernel.api.exception.FedoraInvalidNamespaceException; 027import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 028import org.modeshape.jcr.api.NamespaceRegistry; 029 030/** 031 * Tools for working with the JCR Namespace Registry 032 * (wrapping some non-standard Modeshape machinery) 033 * @author Benjamin Armintor 034 * @since May 13, 2013 035 */ 036public final class NamespaceTools { 037 038 private NamespaceTools() { 039 } 040 041 /** 042 * We need the Modeshape NamespaceRegistry, because it allows us to register 043 * anonymous namespaces. 044 */ 045 public static Function<Node, NamespaceRegistry> getNamespaceRegistry = new Function<Node, NamespaceRegistry>() { 046 @Override 047 public NamespaceRegistry apply(final Node n) { 048 try { 049 Objects.requireNonNull(n, "null has no Namespace Registry associated with it!"); 050 return (org.modeshape.jcr.api.NamespaceRegistry)n.getSession().getWorkspace().getNamespaceRegistry(); 051 } catch (final RepositoryException e) { 052 throw new IllegalStateException(e); 053 } 054 } 055 056 }; 057 058 /** 059 * Return the javax.jcr.NamespaceRegistry associated with the arg session. 060 * 061 * @param session containing the NamespaceRegistry 062 * @return NamespaceRegistry 063 */ 064 public static javax.jcr.NamespaceRegistry getNamespaceRegistry(final Session session) { 065 final javax.jcr.NamespaceRegistry namespaceRegistry; 066 try { 067 namespaceRegistry = 068 session.getWorkspace().getNamespaceRegistry(); 069 Objects.requireNonNull(namespaceRegistry, 070 "Couldn't find namespace registry in repository!"); 071 return namespaceRegistry; 072 } catch (final RepositoryException e) { 073 throw new RepositoryRuntimeException(e); 074 } 075 } 076 077 /** 078 * Validate resource path for unregistered namespace prefixes 079 * 080 * @param session the JCR session to use 081 * @param path the absolute path to the object 082 * @throws org.fcrepo.kernel.api.exception.FedoraInvalidNamespaceException on unregistered namespaces 083 * @throws org.fcrepo.kernel.api.exception.RepositoryRuntimeException if repository runtime exception occurred 084 */ 085 public static void validatePath(final Session session, final String path) { 086 087 final javax.jcr.NamespaceRegistry namespaceRegistry = getNamespaceRegistry(session); 088 089 final String relPath = path.replaceAll("^/+", "").replaceAll("/+$", ""); 090 final String[] pathSegments = relPath.split("/"); 091 for (final String segment : pathSegments) { 092 if (segment.length() > 0 && segment.contains(":") && 093 !segment.substring(0, segment.indexOf(':')).equals("fedora")) { 094 final String prefix = segment.substring(0, segment.indexOf(':')); 095 if (prefix.length() == 0) { 096 throw new FedoraInvalidNamespaceException( 097 String.format("Unable to identify namespace for (%s)", segment)); 098 } 099 try { 100 namespaceRegistry.getURI(prefix); 101 } catch (final NamespaceException e) { 102 throw new FedoraInvalidNamespaceException( 103 String.format("The namespace prefix (%s) has not been registered", prefix), e); 104 } catch (final RepositoryException e) { 105 throw new RepositoryRuntimeException(e); 106 } 107 } 108 } 109 } 110 111}