de.sub.goobi.metadaten.copier.LocalMetadataSelector.java Source code

Java tutorial

Introduction

Here is the source code for de.sub.goobi.metadaten.copier.LocalMetadataSelector.java

Source

/*
 * (c) Kitodo. Key to digital objects e. V. <contact@kitodo.org>
 *
 * This file is part of the Kitodo project.
 *
 * It is licensed under GNU General Public License version 3 or later.
 *
 * For the full copyright and license information, please read the
 * GPL3-License.txt file that was distributed with this source code.
 */

package de.sub.goobi.metadaten.copier;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import ugh.dl.DocStruct;
import ugh.dl.Metadata;
import ugh.dl.MetadataType;
import ugh.exceptions.MetadataTypeNotAllowedException;

/**
 * A LocalMetadataSelector provides methods to retrieve or modify metadata on a
 * document structure node.
 * 
 * @author Matthias Ronge &lt;matthias.ronge@zeutschel.de&gt;
 */
public class LocalMetadataSelector extends MetadataSelector {
    private static final Logger logger = LogManager.getLogger(LocalMetadataSelector.class);

    /**
     * Metadata type to return.
     */
    private final MetadataType selector = new MetadataType();

    /**
     * Creates a new LocalMetadataSelector.
     *
     * @param path
     *            Path to metadatum, must consist of an @? character followed
     *            by a metadata element name, i.e. @TitleDocMain?
     * @throws ConfigurationException
     *             if the metadata path doesnt start with an @? character
     */
    public LocalMetadataSelector(String path) throws ConfigurationException {
        if (!path.startsWith(METADATA_SEPARATOR)) {
            throw new ConfigurationException(
                    "Cannot create local metadata selector: Path must start with \"@\", but is: " + path);
        }
        selector.setName(path.substring(1));
    }

    /**
     * Checks if no metadata as named by the path is available at that document
     * structure node, and only in this case adds a metadata as named by the
     * path with the value passed to the function.
     *
     * @param data
     *            document to work on, required to access the rule set
     * @param logicalNode
     *            document structure node to check and enrich
     * @param value
     *            value to write if no metadatum of this type is available
     * @see de.sub.goobi.metadaten.copier.MetadataSelector#createIfPathExistsOnly(
     *      de.sub.goobi.metadaten.copier.CopierData, ugh.dl.DocStruct,
     *      java.lang.String)
     */
    @Override
    protected void createIfPathExistsOnly(CopierData data, DocStruct logicalNode, String value) {
        if (findMetadatumIn(logicalNode) != null) {
            return;
        }
        tryToCreateANewMetadatum(data, logicalNode, value);
    }

    /**
     * Sets the value of the metadata described by the path to the value passed
     * to the function or creates a metadata as described by the path,
     * respectively.
     *
     * @param data
     *            document to work on, required to access the rule set
     * @param logicalNode
     *            document structure node to check and enrich
     * @param value
     *            value to write if no metadatum of this type is available
     * @see de.sub.goobi.metadaten.copier.MetadataSelector#createIfPathExistsOnly(
     *      de.sub.goobi.metadaten.copier.CopierData, ugh.dl.DocStruct,
     *      java.lang.String)
     */

    @Override
    protected void createOrOverwrite(CopierData data, DocStruct logicalNode, String value) {
        Metadata existingMetadatum = findMetadatumIn(logicalNode);
        if (existingMetadatum != null) {
            existingMetadatum.setValue(value);
        } else {
            tryToCreateANewMetadatum(data, logicalNode, value);
        }
    }

    /**
     * Returns all concrete metadata selectors the potentially generic metadata
     * selector expression resolves to.
     *
     * @param node
     *            Node of the logical document structure to work on
     * @return all metadata selectors the expression resolves to
     * @see de.sub.goobi.metadaten.copier.MetadataSelector#findAll(ugh.dl.DocStruct)
     */
    @Override
    protected Iterable<MetadataSelector> findAll(DocStruct node) {
        ArrayList<MetadataSelector> result = new ArrayList<>(1);
        List<MetadataType> addableTypes = node.getAddableMetadataTypes();
        if (addableTypes != null) {
            for (MetadataType addable : addableTypes) {
                if (selector.getName().equals(addable.getName())) {
                    result.add(this);
                    break;
                }
            }
        }
        return result;
    }

    /**
     * Return the value of the metadata named by the path used to construct the
     * metadata selector, or null if no such metadata is available here.
     *
     * @param node
     *            document structure node to examine
     * @return the value of the metadata, or null if absent
     * @see de.sub.goobi.metadaten.copier.MetadataSelector#findIn(ugh.dl.DocStruct)
     */
    @Override
    protected String findIn(DocStruct node) {
        Metadata found = findMetadatumIn(node);
        return found != null ? found.getValue() : null;
    }

    /**
     * Returns the metadata named by the path used to construct the metadata
     * selector, or null if no such metadata is available here.
     *
     * @param node
     *            document structure node to examine
     * @return the metadata, or null if absent
     * @see de.sub.goobi.metadaten.copier.MetadataSelector#findIn(ugh.dl.DocStruct)
     */
    private Metadata findMetadatumIn(DocStruct node) {
        List<? extends Metadata> metadata = node.getAllMetadataByType(selector);
        for (Metadata metadatum : metadata) {
            if (selector.getName().equals(metadatum.getType().getName())) {
                return metadatum;
            }
        }
        return null;
    }

    /**
     * Returns a string that textually represents this LocalMetadataSelector.
     *
     * @return a string representation of this LocalMetadataSelector
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return METADATA_SEPARATOR + selector.getName();
    }

    /**
     * Adds a metadata as named by the path with the value passed to the
     * function. Doesnt do anything if that isnt possible.
     *
     * @param data
     *            document to work on, required to access the rule set
     * @param logicalNode
     *            document structure node to check and enrich
     * @param value
     *            value to write if no metadataof this type is available
     */
    private void tryToCreateANewMetadatum(CopierData data, DocStruct logicalNode, String value) {
        Metadata copy = null;
        try {
            copy = new Metadata(data.getPreferences().getMetadataTypeByName(selector.getName()));
        } catch (MetadataTypeNotAllowedException e) {
            // copy rules arent related to the rule set but depend on it, so
            // copy rules that dont work with the current rule set are ignored
            if (logger.isDebugEnabled()) {
                logger.debug("Cannot create metadata element " + selector.getName()
                        + ": The type isnt defined by the rule set used.");
            }
            return;
        } catch (Exception e) {
            // copy rule failed, skip it
            if (logger.isDebugEnabled()) {
                logger.debug("Cannot create metadata element " + selector.getName()
                        + ": Accessing the rule set failed with exception: "
                        + (e.getMessage() != null ? e.getMessage() : e.getClass().getSimpleName()), e);
            }
            return;
        }
        try {
            copy.setValue(value);
            logicalNode.addMetadata(copy);
        } catch (MetadataTypeNotAllowedException e) {
            // copy rules arent related to the rule set but depend on it, so
            // copy rules that dont work with the current rule set are ignored
            if (logger.isDebugEnabled()) {
                logger.debug("Cannot assign metadata element " + selector.getName() + " (\"" + value
                        + "\") to structural element "
                        + (logicalNode.getType() != null ? logicalNode.getType().getName() : "without type") + ": "
                        + e.getMessage());
            }
        }
    }
}