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