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.modeshape.rdf.impl.mappings; 017 018import static com.hp.hpl.jena.datatypes.xsd.XSDDatatype.XSDstring; 019import static com.hp.hpl.jena.graph.NodeFactory.createLiteral; 020import static com.hp.hpl.jena.graph.Triple.create; 021import static org.fcrepo.kernel.modeshape.identifiers.NodeResourceConverter.nodeToResource; 022import java.util.Iterator; 023import java.util.function.Function; 024 025import javax.jcr.Node; 026import javax.jcr.Property; 027import javax.jcr.RepositoryException; 028import javax.jcr.Session; 029import com.google.common.base.Converter; 030import com.google.common.collect.Iterators; 031import com.hp.hpl.jena.graph.impl.LiteralLabel; 032import com.hp.hpl.jena.rdf.model.Resource; 033 034import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 035import org.fcrepo.kernel.api.models.FedoraResource; 036import org.fcrepo.kernel.modeshape.rdf.converters.PropertyConverter; 037import org.fcrepo.kernel.modeshape.rdf.converters.ValueConverter; 038import com.hp.hpl.jena.datatypes.RDFDatatype; 039import com.hp.hpl.jena.graph.Triple; 040 041/** 042 * Utility for moving from JCR properties to RDF triples. 043 * 044 * @author ajs6f 045 * @since Oct 10, 2013 046 */ 047public class PropertyToTriple implements Function<Property, Iterator<Triple>> { 048 049 private static final PropertyConverter propertyConverter = new PropertyConverter(); 050 private final ValueConverter valueConverter; 051 private final Converter<Node, Resource> translator; 052 053 /** 054 * Default constructor. We require a {@link Converter} in order to construct the RDF subjects of our triples. 055 * 056 * @param converter a converter between RDF and the Fedora model 057 * @param session the JCR session 058 */ 059 public PropertyToTriple(final Session session, final Converter<Resource, FedoraResource> converter) { 060 this.valueConverter = new ValueConverter(session, converter); 061 this.translator = nodeToResource(converter); 062 } 063 064 @Override 065 public Iterator<Triple> apply(final Property p) { 066 try { 067 final com.hp.hpl.jena.graph.Node subject = translator.convert(p.getParent()).asNode(); 068 final com.hp.hpl.jena.graph.Node propPredicate = propertyConverter.convert(p).asNode(); 069 final String propertyName = p.getName(); 070 071 return Iterators.transform(new PropertyValueIterator(p), v -> { 072 final com.hp.hpl.jena.graph.Node object = valueConverter.convert(v).asNode(); 073 if (object.isLiteral()) { 074 // unpack the name of the property for information about what kind of literal 075 final int i = propertyName.indexOf('@'); 076 if (i > 0) { 077 final LiteralLabel literal = object.getLiteral(); 078 final RDFDatatype datatype = literal.getDatatype(); 079 final String datatypeURI = datatype.getURI(); 080 if (datatypeURI.isEmpty() || datatype.equals(XSDstring)) { 081 // this is an RDF string literal and could involve an RDF lang tag 082 final String lang = propertyName.substring(i + 1); 083 final String lex = literal.getLexicalForm(); 084 return create(subject, propPredicate, createLiteral(lex, lang, datatype)); 085 } 086 } 087 } 088 return create(subject, propPredicate, object); 089 }); 090 } catch (final RepositoryException e) { 091 throw new RepositoryRuntimeException(e); 092 } 093 } 094}