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