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