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.impl.rdf.impl; 017 018import static com.google.common.collect.Lists.newArrayList; 019import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; 020 021import com.google.common.base.Converter; 022import com.google.common.collect.Lists; 023 024import org.fcrepo.kernel.models.FedoraResource; 025import org.fcrepo.kernel.exception.RepositoryRuntimeException; 026import org.fcrepo.kernel.identifiers.IdentifierConverter; 027 028import com.hp.hpl.jena.rdf.model.Resource; 029 030import org.fcrepo.kernel.impl.identifiers.HashConverter; 031import org.fcrepo.kernel.impl.identifiers.NamespaceConverter; 032import org.fcrepo.kernel.impl.identifiers.NodeResourceConverter; 033 034import javax.jcr.RepositoryException; 035import javax.jcr.Session; 036 037import java.util.List; 038 039/** 040 * A very simple {@link IdentifierConverter} which translates JCR paths into 041 * un-dereference-able Fedora subjects (by replacing JCR-specific names with 042 * Fedora names). Should not be used except in "embedded" deployments in which 043 * no publication of translated identifiers is expected! 044 * 045 * @author barmintor 046 * @author ajs6f 047 * @since May 15, 2013 048 */ 049public class DefaultIdentifierTranslator extends IdentifierConverter<Resource, FedoraResource> { 050 051 052 private static final NodeResourceConverter nodeResourceConverter = new NodeResourceConverter(); 053 054 /** 055 * Default namespace to use for node URIs 056 */ 057 public static final String RESOURCE_NAMESPACE = "info:fedora/"; 058 private final Session session; 059 060 /** 061 * Construct the graph with a placeholder context resource 062 * @param session the session 063 */ 064 public DefaultIdentifierTranslator(final Session session) { 065 this.session = session; 066 setTranslationChain(); 067 } 068 069 070 protected Converter<String, String> forward = identity(); 071 protected Converter<String, String> reverse = identity(); 072 073 private void setTranslationChain() { 074 075 for (final Converter<String, String> t : minimalTranslationChain) { 076 forward = forward.andThen(t); 077 } 078 for (final Converter<String, String> t : Lists.reverse(minimalTranslationChain)) { 079 reverse = reverse.andThen(t.reverse()); 080 } 081 } 082 083 084 @SuppressWarnings("unchecked") 085 private static final List<Converter<String, String>> minimalTranslationChain = 086 newArrayList((Converter<String, String>) new NamespaceConverter(), 087 (Converter<String, String>) new HashConverter() 088 ); 089 090 @Override 091 protected FedoraResource doForward(final Resource subject) { 092 try { 093 if (!inDomain(subject)) { 094 throw new RepositoryRuntimeException("Subject " + subject + " is not in this repository"); 095 } 096 097 return nodeResourceConverter.convert(session.getNode(asString(subject))); 098 } catch (final RepositoryException e) { 099 throw new RepositoryRuntimeException(e); 100 } 101 } 102 103 @Override 104 protected Resource doBackward(final FedoraResource resource) { 105 final String absPath = resource.getPath(); 106 107 return toDomain(absPath); 108 } 109 110 @Override 111 public boolean inDomain(final Resource subject) { 112 return subject.isURIResource() && subject.getURI().startsWith(RESOURCE_NAMESPACE); 113 } 114 115 @Override 116 public Resource toDomain(final String absPath) { 117 final String relativePath; 118 119 if (absPath.startsWith("/")) { 120 relativePath = absPath.substring(1); 121 } else { 122 relativePath = absPath; 123 } 124 return createResource(RESOURCE_NAMESPACE + reverse.convert(relativePath)); 125 } 126 127 @Override 128 public String asString(final Resource subject) { 129 if (!inDomain(subject)) { 130 return null; 131 } 132 133 final String path = subject.getURI().substring(RESOURCE_NAMESPACE.length() - 1); 134 135 final String absPath = forward.convert(path); 136 137 if (absPath.isEmpty()) { 138 return "/"; 139 } 140 return absPath; 141 } 142 143}