001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.kernel.modeshape.rdf.impl.mappings; 019 020import static org.apache.jena.datatypes.xsd.XSDDatatype.XSDstring; 021import static org.apache.jena.graph.NodeFactory.createLiteral; 022import static org.apache.jena.graph.Triple.create; 023import static org.fcrepo.kernel.modeshape.identifiers.NodeResourceConverter.nodeToResource; 024import static org.fcrepo.kernel.modeshape.utils.StreamUtils.iteratorToStream; 025 026import java.util.function.Function; 027import java.util.stream.Stream; 028 029import javax.jcr.Node; 030import javax.jcr.Property; 031import javax.jcr.RepositoryException; 032import javax.jcr.Session; 033import com.google.common.base.Converter; 034import org.apache.jena.graph.impl.LiteralLabel; 035import org.apache.jena.rdf.model.Resource; 036 037import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 038import org.fcrepo.kernel.api.models.FedoraResource; 039import org.fcrepo.kernel.modeshape.rdf.converters.PropertyConverter; 040import org.fcrepo.kernel.modeshape.rdf.converters.ValueConverter; 041import org.apache.jena.datatypes.RDFDatatype; 042import org.apache.jena.graph.Triple; 043 044/** 045 * Utility for moving from JCR properties to RDF triples. 046 * 047 * @author ajs6f 048 * @since Oct 10, 2013 049 */ 050public class PropertyToTriple implements Function<Property, Stream<Triple>> { 051 052 private static final PropertyConverter propertyConverter = new PropertyConverter(); 053 private final ValueConverter valueConverter; 054 private final Converter<Node, Resource> translator; 055 056 /** 057 * Default constructor. We require a {@link Converter} in order to construct the RDF subjects of our triples. 058 * 059 * @param converter a converter between RDF and the Fedora model 060 * @param session the JCR session 061 */ 062 public PropertyToTriple(final Session session, final Converter<Resource, FedoraResource> converter) { 063 this.valueConverter = new ValueConverter(session, converter); 064 this.translator = nodeToResource(converter); 065 } 066 067 @Override 068 public Stream<Triple> apply(final Property p) { 069 try { 070 final org.apache.jena.graph.Node subject = translator.convert(p.getParent()).asNode(); 071 final org.apache.jena.graph.Node propPredicate = propertyConverter.convert(p).asNode(); 072 final String propertyName = p.getName(); 073 074 return iteratorToStream(new PropertyValueIterator(p)).map(v -> { 075 final org.apache.jena.graph.Node object = valueConverter.convert(v).asNode(); 076 if (object.isLiteral()) { 077 // unpack the name of the property for information about what kind of literal 078 final int i = propertyName.indexOf('@'); 079 if (i > 0) { 080 final LiteralLabel literal = object.getLiteral(); 081 final RDFDatatype datatype = literal.getDatatype(); 082 final String datatypeURI = datatype.getURI(); 083 if (datatypeURI.isEmpty() || datatype.equals(XSDstring)) { 084 // this is an RDF string literal and could involve an RDF lang tag 085 final String lang = propertyName.substring(i + 1); 086 final String lex = literal.getLexicalForm(); 087 return create(subject, propPredicate, createLiteral(lex, lang, datatype)); 088 } 089 } 090 } 091 return create(subject, propPredicate, object); 092 }); 093 } catch (final RepositoryException e) { 094 throw new RepositoryRuntimeException(e); 095 } 096 } 097}