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.sword.protocol;
017
018import org.apache.abdera.Abdera;
019import org.apache.abdera.model.Service;
020import org.fcrepo.kernel.api.models.Container;
021import org.fcrepo.kernel.api.models.FedoraResource;
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025import javax.jcr.RepositoryException;
026import javax.jcr.Value;
027
028import static org.fcrepo.sword.protocol.SWORDProtocol.SWORD_TERMS_NAMESPACE;
029import static org.fcrepo.sword.protocol.SWORDProtocol.SWORD_VERSION;
030
031/**
032 * Builder for a SWORD service document using Abdera ATOM library
033 *
034 * @author claussni
035 */
036public class SWORDServiceDocumentBuilder {
037
038    private Abdera    abdera;
039    private Integer   maxUploadSize;
040    private Container workspaces;
041    private Logger    log;
042
043    /**
044     * Create a new builder
045     *
046     * @param abdera Abdera implementation to use
047     * @param log    Logger implementation to use. If none is given, a default logger for this class is used.
048     */
049    public SWORDServiceDocumentBuilder(final Abdera abdera, final Logger log) {
050        this.abdera = abdera;
051        this.log = (log == null) ? LoggerFactory.getLogger(SWORDServiceDocumentBuilder.class) : log;
052    }
053
054    /**
055     * Set the maxUploadSize parameter
056     *
057     * @param swordMaxUploadSizeKb Maximum size of uploads in kilobytes
058     * @return The builder object
059     */
060    public SWORDServiceDocumentBuilder maxUploadSize(final Integer swordMaxUploadSizeKb) {
061        this.maxUploadSize = swordMaxUploadSizeKb;
062        return this;
063    }
064
065    /**
066     * Set the Fedora container resource containing the SWORD workspace nodes
067     *
068     * @param workspaces Container with workspace nodes
069     * @return The builder object
070     */
071    public SWORDServiceDocumentBuilder workspacesContainer(final Container workspaces) {
072        this.workspaces = workspaces;
073        return this;
074    }
075
076    /**
077     * Build and return the service document containing the configured parameters and detected workspaces
078     *
079     * @return A SWORD service document
080     */
081    public Service serviceDocument() {
082        final Service service = abdera.newService();
083        service.addSimpleExtension(SWORD_TERMS_NAMESPACE, "version", "sword", SWORD_VERSION);
084        service.addSimpleExtension(SWORD_TERMS_NAMESPACE, "maxUploadSize", "sword", String.valueOf(maxUploadSize));
085        workspaces.getChildren().forEachRemaining(fedoraResource -> addWorkspace(service, fedoraResource));
086        return service;
087    }
088
089    private void addWorkspace(final Service service, final FedoraResource fedoraResource) {
090        try {
091            final Value[] dcTitles = fedoraResource.getProperty("dc:title").getValues();
092            if (dcTitles.length > 0) {
093                try {
094                    final String title = dcTitles[0].getString();
095                    if (!title.isEmpty()) {
096                        service.addWorkspace(title);
097                    }
098                } catch (IndexOutOfBoundsException | NullPointerException e) {
099                    log.warn("Found workspace container without dc:title property: {}", fedoraResource.getPath());
100                }
101            }
102        } catch (RepositoryException e) {
103            log.warn("Found workspace container with invalid dc:title property: {}", fedoraResource.getPath());
104        }
105    }
106
107}