001/** 002 * Copyright 2014 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 */ 063 public DefaultIdentifierTranslator(final Session session) { 064 this.session = session; 065 setTranslationChain(); 066 } 067 068 069 protected Converter<String, String> forward = identity(); 070 protected Converter<String, String> reverse = identity(); 071 072 private void setTranslationChain() { 073 074 for (final Converter<String, String> t : minimalTranslationChain) { 075 forward = forward.andThen(t); 076 } 077 for (final Converter<String, String> t : Lists.reverse(minimalTranslationChain)) { 078 reverse = reverse.andThen(t.reverse()); 079 } 080 } 081 082 083 @SuppressWarnings("unchecked") 084 private static final List<Converter<String, String>> minimalTranslationChain = 085 newArrayList((Converter<String, String>) new NamespaceConverter(), 086 (Converter<String, String>) new HashConverter() 087 ); 088 089 @Override 090 protected FedoraResource doForward(final Resource subject) { 091 try { 092 if (!inDomain(subject)) { 093 throw new RepositoryRuntimeException("Subject " + subject + " is not in this repository"); 094 } 095 096 return nodeResourceConverter.convert(session.getNode(asString(subject))); 097 } catch (final RepositoryException e) { 098 throw new RepositoryRuntimeException(e); 099 } 100 } 101 102 @Override 103 protected Resource doBackward(final FedoraResource resource) { 104 final String absPath = resource.getPath(); 105 106 return toDomain(absPath); 107 } 108 109 @Override 110 public boolean inDomain(final Resource subject) { 111 return subject.isURIResource() && subject.getURI().startsWith(RESOURCE_NAMESPACE); 112 } 113 114 @Override 115 public Resource toDomain(final String absPath) { 116 final String relativePath; 117 118 if (absPath.startsWith("/")) { 119 relativePath = absPath.substring(1); 120 } else { 121 relativePath = absPath; 122 } 123 return createResource(RESOURCE_NAMESPACE + reverse.convert(relativePath)); 124 } 125 126 @Override 127 public String asString(final Resource subject) { 128 if (!inDomain(subject)) { 129 return null; 130 } 131 132 final String path = subject.getURI().substring(RESOURCE_NAMESPACE.length() - 1); 133 134 final String absPath = forward.convert(path); 135 136 if (absPath.isEmpty()) { 137 return "/"; 138 } 139 return absPath; 140 } 141 142}