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.http.api.url;
017
018import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel;
019import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource;
020import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
021import static java.util.Collections.singletonMap;
022import static org.fcrepo.kernel.FedoraJcrTypes.ROOT;
023import static org.fcrepo.kernel.RdfLexicon.HAS_FIXITY_SERVICE;
024import static org.fcrepo.kernel.RdfLexicon.HAS_SERIALIZATION;
025import static org.fcrepo.kernel.RdfLexicon.HAS_TRANSACTION_SERVICE;
026import static org.fcrepo.kernel.RdfLexicon.HAS_VERSION_HISTORY;
027import static org.fcrepo.kernel.RdfLexicon.RDFS_LABEL;
028import static org.fcrepo.kernel.RdfLexicon.REPOSITORY_NAMESPACE;
029import static org.fcrepo.kernel.RdfLexicon.DC_NAMESPACE;
030
031import com.hp.hpl.jena.rdf.model.Model;
032import com.hp.hpl.jena.rdf.model.Property;
033import com.hp.hpl.jena.rdf.model.Resource;
034
035import org.fcrepo.http.api.FedoraExport;
036import org.fcrepo.http.api.FedoraVersioning;
037import org.fcrepo.http.api.repository.FedoraRepositoryExport;
038import org.fcrepo.http.api.repository.FedoraRepositoryTransactions;
039import org.fcrepo.http.commons.api.rdf.UriAwareResourceModelFactory;
040import org.fcrepo.kernel.models.NonRdfSource;
041import org.fcrepo.kernel.models.NonRdfSourceDescription;
042import org.fcrepo.kernel.models.FedoraBinary;
043import org.fcrepo.kernel.models.FedoraResource;
044import org.fcrepo.kernel.identifiers.IdentifierConverter;
045import org.fcrepo.serialization.SerializerUtil;
046
047import org.springframework.beans.factory.annotation.Autowired;
048import org.springframework.stereotype.Component;
049
050import javax.ws.rs.core.UriInfo;
051
052import java.util.Map;
053
054/**
055 * Inject our HTTP API methods into the object graphs
056 *
057 * @author awoods
058 */
059@Component
060public class HttpApiResources implements UriAwareResourceModelFactory {
061
062    @Autowired
063    protected SerializerUtil serializers;
064
065    @Override
066    public Model createModelForResource(final FedoraResource resource,
067        final UriInfo uriInfo, final IdentifierConverter<Resource,FedoraResource> idTranslator) {
068
069        final Model model = createDefaultModel();
070
071        final Resource s = idTranslator.reverse().convert(resource);
072
073        if (resource.hasType(ROOT)) {
074            addRepositoryStatements(uriInfo, model, s);
075        } else {
076            addNodeStatements(resource, uriInfo, model, s);
077        }
078
079        if (resource instanceof NonRdfSourceDescription) {
080            final NonRdfSource describedResource = ((NonRdfSourceDescription) resource).getDescribedResource();
081
082            if (describedResource instanceof FedoraBinary) {
083                addContentStatements(idTranslator, (FedoraBinary)describedResource, model);
084            }
085        } else if (resource instanceof FedoraBinary) {
086            addContentStatements(idTranslator, (FedoraBinary)resource, model);
087        }
088
089        return model;
090    }
091
092    private static void addContentStatements(final IdentifierConverter<Resource,FedoraResource> idTranslator,
093                                             final FedoraBinary resource,
094                                             final Model model) {
095        // fcr:fixity
096        final Resource subject = idTranslator.reverse().convert(resource);
097        model.add(subject, HAS_FIXITY_SERVICE, createResource(subject.getURI() +
098                "/fcr:fixity"));
099    }
100
101    private void addNodeStatements(final FedoraResource resource, final UriInfo uriInfo,
102        final Model model, final Resource s) {
103
104        final Map<String, String> pathMap =
105                singletonMap("path", resource.getPath().substring(1));
106
107        // fcr:versions
108        if (resource.isVersioned()) {
109            model.add(s, HAS_VERSION_HISTORY, createResource(uriInfo
110                    .getBaseUriBuilder().path(FedoraVersioning.class).buildFromMap(
111                            pathMap, false).toASCIIString()));
112        }
113
114        final Property dcFormat = createProperty(DC_NAMESPACE + "format");
115        // fcr:exports?format=xyz
116        for (final String key : serializers.keySet()) {
117            if (serializers.getSerializer(key).canSerialize(resource)) {
118                final Resource format =
119                        createResource(uriInfo.getBaseUriBuilder().path(
120                                FedoraExport.class).queryParam("format", key)
121                                .buildFromMap(pathMap, false).toASCIIString());
122                model.add(s, HAS_SERIALIZATION, format);
123
124                //RDF the serialization
125                final Resource formatRDF = createResource(REPOSITORY_NAMESPACE + key);
126
127                model.add(formatRDF, RDFS_LABEL, key);
128                model.add(format, dcFormat, formatRDF);
129            }
130        }
131    }
132
133    private void addRepositoryStatements(final UriInfo uriInfo, final Model model,
134        final Resource s) {
135        // fcr:tx
136        model.add(s, HAS_TRANSACTION_SERVICE, createResource(uriInfo
137                .getBaseUriBuilder().path(FedoraRepositoryTransactions.class)
138                .build().toASCIIString()));
139
140        final Property dcFormat = createProperty(DC_NAMESPACE + "format");
141        // fcr:export?format=xyz
142        for (final String key : serializers.keySet()) {
143            final Resource format = createResource(uriInfo
144                .getBaseUriBuilder().path(FedoraRepositoryExport.class)
145                .queryParam("format", key).build().toASCIIString());
146            model.add(s, HAS_SERIALIZATION, format);
147            final Resource formatRDF = createResource(REPOSITORY_NAMESPACE + key);
148
149            model.add(formatRDF, RDFS_LABEL, key);
150            model.add(format, dcFormat, formatRDF);
151        }
152    }
153
154}