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 */ 016 017package org.fcrepo.kernel.impl.rdf.converters; 018 019import com.google.common.base.Converter; 020import com.google.common.collect.ImmutableBiMap; 021import com.hp.hpl.jena.rdf.model.Property; 022import com.hp.hpl.jena.rdf.model.Resource; 023import org.modeshape.jcr.api.NamespaceRegistry; 024import org.modeshape.jcr.api.Namespaced; 025import org.slf4j.Logger; 026 027import javax.jcr.Node; 028import javax.jcr.RepositoryException; 029 030import java.util.Map; 031 032import static com.google.common.base.Throwables.propagate; 033import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty; 034import static org.fcrepo.kernel.impl.rdf.JcrRdfTools.getJcrNamespaceForRDFNamespace; 035import static org.fcrepo.kernel.impl.rdf.JcrRdfTools.getRDFNamespaceForJcrNamespace; 036import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.getReferencePropertyOriginalName; 037import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isInternalReferenceProperty; 038import static org.fcrepo.kernel.utils.NamespaceTools.getNamespaceRegistry; 039import static org.slf4j.LoggerFactory.getLogger; 040 041 042/** 043 * Convert between RDF properties and JCR properties 044 * @author cabeer 045 * @since 10/8/14 046 */ 047public class PropertyConverter extends Converter<javax.jcr.Property, Property> { 048 private static final Logger LOGGER = getLogger(PropertyConverter.class); 049 050 @Override 051 protected Property doForward(final javax.jcr.Property property) { 052 LOGGER.trace("Creating predicate for property: {}", 053 property); 054 try { 055 if (property instanceof Namespaced) { 056 final Namespaced nsProperty = (Namespaced) property; 057 final String uri = nsProperty.getNamespaceURI(); 058 final String localName = nsProperty.getLocalName(); 059 final String rdfLocalName; 060 061 if (isInternalReferenceProperty.apply(property)) { 062 rdfLocalName = getReferencePropertyOriginalName(localName); 063 } else { 064 rdfLocalName = localName; 065 } 066 return createProperty( 067 getRDFNamespaceForJcrNamespace(uri), 068 rdfLocalName); 069 } 070 return createProperty(property.getName()); 071 } catch (final RepositoryException e) { 072 throw propagate(e); 073 } 074 075 } 076 077 @Override 078 protected javax.jcr.Property doBackward(final Property property) { 079 throw new UnsupportedOperationException(); 080 } 081 082 /** 083 * Given an RDF predicate value (namespace URI + local name), figure out 084 * what JCR property to use 085 * 086 * @param node the JCR node we want a property for 087 * @param predicate the predicate to map to a property name 088 * @param namespaceMapping prefix to uri namespace mapping 089 * @return the JCR property name 090 * @throws RepositoryException 091 */ 092 public static String getPropertyNameFromPredicate(final Node node, 093 final Resource predicate, 094 final Map<String, String> namespaceMapping) 095 throws RepositoryException { 096 final NamespaceRegistry namespaceRegistry = getNamespaceRegistry.apply(node); 097 return getPropertyNameFromPredicate(namespaceRegistry, 098 predicate, namespaceMapping); 099 } 100 101 /** 102 * Get the JCR property name for an RDF predicate 103 * 104 * @param namespaceRegistry 105 * @param predicate the predicate to map to a property name 106 * @param namespaceMapping 107 * @return JCR property name for an RDF predicate 108 * @throws RepositoryException 109 */ 110 public static String getPropertyNameFromPredicate(final NamespaceRegistry namespaceRegistry, 111 final Resource predicate, 112 final Map<String, String> namespaceMapping) 113 throws RepositoryException { 114 115 final String rdfNamespace = predicate.getNameSpace(); 116 final String rdfLocalname = predicate.getLocalName(); 117 118 final String prefix; 119 120 final String namespace = getJcrNamespaceForRDFNamespace(rdfNamespace); 121 122 assert (namespaceRegistry != null); 123 124 if (namespaceRegistry.isRegisteredUri(namespace)) { 125 LOGGER.debug("Discovered namespace: {} in namespace registry.",namespace); 126 prefix = namespaceRegistry.getPrefix(namespace); 127 } else { 128 LOGGER.debug("Didn't discover namespace: {} in namespace registry.",namespace); 129 final ImmutableBiMap<String, String> nsMap = 130 ImmutableBiMap.copyOf(namespaceMapping); 131 if (nsMap.containsValue(namespace)) { 132 LOGGER.debug("Discovered namespace: {} in namespace map: {}.", namespace, 133 nsMap); 134 prefix = nsMap.inverse().get(namespace); 135 namespaceRegistry.registerNamespace(prefix, namespace); 136 } else { 137 prefix = namespaceRegistry.registerNamespace(namespace); 138 } 139 } 140 141 final String propertyName = prefix + ":" + rdfLocalname; 142 143 LOGGER.debug("Took RDF predicate {} and translated it to JCR property {}", namespace, propertyName); 144 145 return propertyName; 146 147 } 148 149}