Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* This file is part of *** M y C o R e ***
* See http://www.mycore.de/ for details.
*
* MyCoRe is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MyCoRe is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MyCoRe. If not, see .
*/
package org.mycore.datamodel.metadata;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jdom2.Element;
import org.mycore.common.MCRException;
import org.mycore.common.config.MCRConfiguration2;
import org.mycore.common.config.MCRConfigurationException;
import com.google.gson.JsonObject;
/**
* This class implements all methode for handling one object metadata part. This
* class uses only metadata type classes of the general datamodel code of
* MyCoRe.
*
* @author Jens Kupferschmidt
* @author Mathias Hegner
* @version $Revision$ $Date$
*/
public class MCRObjectMetadata implements Iterable {
private static final Logger LOGGER = LogManager.getLogger();
// common data
private boolean heritedXML;
// metadata list
private final ArrayList metadataElements;
/**
* This is the constructor of the MCRObjectMetadata class. It set the
* default language for all metadata to the value from the configuration
* propertie MCR.Metadata.DefaultLang.
*
* @exception MCRConfigurationException
* a special exception for configuartion data
*/
public MCRObjectMetadata() throws MCRConfigurationException {
heritedXML = MCRConfiguration2.getBoolean("MCR.Metadata.HeritedForXML").orElse(true);
metadataElements = new ArrayList<>();
}
/**
* size returns the number of tag names in the ArrayList.
*
* @return int number of tags and meta elements
*/
public int size() {
return metadataElements.size();
}
/**
* getHeritableMetadata returns an instance of MCRObjectMetadata
* containing all the heritable MetaElement's of this object.
*
* @return MCRObjectMetadata the heritable part of this MCRObjectMetadata
*/
public final MCRObjectMetadata getHeritableMetadata() {
MCRObjectMetadata heritableMetadata = new MCRObjectMetadata();
stream().filter(MCRMetaElement::isHeritable).map(MCRMetaElement::clone).forEach(metaElement -> {
metaElement.stream().forEach(MCRMetaInterface::incrementInherited);
heritableMetadata.setMetadataElement(metaElement);
});
return heritableMetadata;
}
/**
* removeInheritedMetadata removes all inherited metadata elements
*/
public final void removeInheritedMetadata() {
Iterator elements = metadataElements.iterator();
while (elements.hasNext()) {
MCRMetaElement me = elements.next();
me.removeInheritedMetadata();
//remove meta element if empty (else isValid() will fail)
if (me.size() == 0) {
elements.remove();
}
}
}
/**
* This method append MCRMetaElement's from a given MCRObjectMetadata to
* this data set.
*
* @param input
* the MCRObjectMetadata, that should merged into this data set
*/
public final void appendMetadata(MCRObjectMetadata input) {
for (MCRMetaElement newelm : input) {
int pos = -1;
for (int j = 0; j < size(); j++) {
if (metadataElements.get(j)
.getTag()
.equals(newelm.getTag())) {
pos = j;
}
}
if (pos != -1) {
if (!metadataElements.get(pos)
.inheritsNot()) {
metadataElements.get(pos)
.setHeritable(true);
for (int j = 0; j < newelm.size(); j++) {
MCRMetaInterface obj = newelm.getElement(j);
metadataElements.get(pos)
.addMetaObject(obj);
}
}
} else {
metadataElements.add(newelm);
}
}
}
/**
* This method return the MCRMetaElement selected by tag. If this was not
* found, null was returned.
*
* @param tag
* the element tag
* @return the MCRMetaElement for the tag
*/
public final MCRMetaElement getMetadataElement(String tag) {
for (MCRMetaElement sub : this) {
if (sub.getTag().equals(tag)) {
return sub;
}
}
return null;
}
/**
* This method return the MCRMetaElement selected by an index. If this was
* not found, null was returned.
*
* @param index
* the element index
* @return the MCRMetaElement for the index
*/
public final MCRMetaElement getMetadataElement(int index) {
return metadataElements.get(index);
}
/**
* sets the given MCRMetaElement to the list. If the tag exists
* the MCRMetaElement was replaced.
*
* @param obj
* the MCRMetaElement object
*/
public final void setMetadataElement(MCRMetaElement obj) {
MCRMetaElement old = getMetadataElement(obj.getTag());
if (old == null) {
metadataElements.add(obj);
return;
}
int i = metadataElements.indexOf(old);
metadataElements.remove(i);
metadataElements.add(i, obj);
}
/**
* Removes the given element.
*
* @param element the meta element to remove
* @return true if the element was removed
*/
public final boolean removeMetadataElement(MCRMetaElement element) {
return metadataElements.remove(element);
}
/**
* This method remove the MCRMetaElement selected by tag from the list.
*
* @return true if set was successful, otherwise false
*/
public final MCRMetaElement removeMetadataElement(String tag) {
MCRMetaElement old = getMetadataElement(tag);
if (old != null) {
removeMetadataElement(old);
return old;
}
return null;
}
/**
* This method remove the MCRMetaElement selected a index from the list.
*
* @return true if set was successful, otherwise false
*/
public final MCRMetaElement removeMetadataElement(int index) {
if (index < 0 || index > size()) {
return null;
}
return metadataElements.remove(index);
}
/**
* Finds the first, not inherited {@link MCRMetaInterface} with the given tag.
*
* @param tag the metadata tag e.g. 'maintitles'
* @return an optional of the first meta interface
*/
public final Optional findFirst(String tag) {
return findFirst(tag, null, 0);
}
/**
* Finds the first, not inherited {@link MCRMetaInterface} with the given tag
* where the @type attribute is equal to the given type. If the type is null,
* this method doesn't care if the @type attribute is set or not.
*
* @param tag the metadata tag e.g. 'subtitles'
* @param type the @type attribute which have to match
* @return an optional of the first meta interface
*/
public final Optional findFirst(String tag, String type) {
return findFirst(tag, type, 0);
}
/**
* Finds the first {@link MCRMetaInterface} with the given tag where the
* inheritance level is equal the inherited value.
*
* @param tag the metadata tag e.g. 'maintitles'
* @param inherited level of inheritance. Zero is the current level,
* parent is one and so on.
* @return an optional of the first meta interface
*/
public final Optional findFirst(String tag, Integer inherited) {
return findFirst(tag, null, inherited);
}
/**
* Finds the first {@link MCRMetaInterface} with the given tag where the
* inheritance level is equal the inherited value and the @type attribute
* is equal to the given type. If the type is null, this method doesn't
* care if the @type attribute is set or not.
*
* @param tag the metadata tag e.g. 'subtitles'
* @param type the @type attribute which have to match
* @param inherited level of inheritance. Zero is the current level,
* parent is one and so on.
* @return an optional of the first meta interface
*/
public final Optional findFirst(String tag, String type, Integer inherited) {
Stream stream = stream(tag);
return stream.filter(filterByType(type))
.filter(filterByInherited(inherited))
.findFirst();
}
/**
* Streams the {@link MCRMetaElement}'s.
*
* @return stream of MCRMetaElement's
*/
public final Stream stream() {
return metadataElements.stream();
}
/**
* Streams the {@link MCRMetaInterface}s of the given tag.
*
*
* @param tag tag the metadata tag e.g. 'maintitles'
* @return a stream of the requested meta interfaces
*/
public final Stream stream(String tag) {
Optional metadata = Optional.ofNullable(getMetadataElement(tag));
// waiting for https://bugs.openjdk.java.net/browse/JDK-8050820
return metadata.map(
mcrMetaInterfaces -> StreamSupport.stream(mcrMetaInterfaces.spliterator(), false).map(metaInterface -> {
@SuppressWarnings("unchecked")
T t = (T) metaInterface;
return t;
})).orElseGet(Stream::empty);
}
/**
* Lists the {@link MCRMetaInterface}s of the given tag. This is not a
* live list. Removals or adds are not reflected on the
* {@link MCRMetaElement}. Use {@link #getMetadataElement(String)}
* for those operations.
*
*
* {@code
* List list = mcrObjectMetadata.list("maintitles");
* }
*
*
* @param tag tag the metadata tag e.g. 'maintitles'
* @return a list of the requested meta interfaces
*/
public final List list(String tag) {
Stream stream = stream(tag);
return stream.collect(Collectors.toList());
}
/**
* Checks if the type of an {@link MCRMetaInterface} is equal
* the given type. If the given type is null, true is returned.
*
* @param type the type to compare
* @return true if the types are equal
*/
private Predicate filterByType(String type) {
return (metaInterface) -> type == null || type.equals(metaInterface.getType());
}
/**
* Checks if the inheritance level of an {@link MCRMetaInterface}
* is equal the given inherited value.
*
* @param inherited the inherited value
* @return true if the inherited values are equal
*/
private Predicate filterByInherited(Integer inherited) {
return (metaInterface) -> metaInterface.getInherited() == inherited;
}
/**
* This methode read the XML input stream part from a DOM part for the
* metadata of the document.
*
* @param element
* a list of relevant DOM elements for the metadata
* @exception MCRException
* if a problem occured
*/
public final void setFromDOM(Element element) throws MCRException {
List elements = element.getChildren();
metadataElements.clear();
for (Element sub : elements) {
MCRMetaElement obj = new MCRMetaElement();
obj.setFromDOM(sub);
metadataElements.add(obj);
}
}
/**
* This methode create a XML stream for all metadata.
*
* @exception MCRException
* if the content of this class is not valid
* @return a JDOM Element with the XML data of the metadata part
*/
public final Element createXML() throws MCRException {
try {
validate();
} catch (MCRException exc) {
throw new MCRException("MCRObjectMetadata : The content is not valid.", exc);
}
Element elm = new Element("metadata");
for (MCRMetaElement e : this) {
elm.addContent(e.createXML(heritedXML));
}
return elm;
}
/**
* Creates the JSON representation of this metadata container.
*
*
*
* @return a json gson representation of this metadata container
*/
public JsonObject createJSON() {
JsonObject metadata = new JsonObject();
StreamSupport.stream(spliterator(), true)
.forEach(metaElement -> metadata.add(metaElement.getTag(), metaElement.createJSON(heritedXML)));
return metadata;
}
/**
* This methode check the validation of the content of this class. The
* methode returns true if
*
*
the array is empty
*
the default lang value was supported
*
* otherwise the methode return false
*
* @return a boolean value
*/
public final boolean isValid() {
try {
validate();
return true;
} catch (MCRException exc) {
LOGGER.warn("The element is invalid.", exc);
}
return false;
}
/**
* Validates this MCRObjectMetadata. This method throws an exception if:
*
*
one of the MCRMetaElement children is invalid
*
*
* @throws MCRException the MCRObjectMetadata is invalid
*/
public void validate() throws MCRException {
for (MCRMetaElement e : this) {
try {
e.validate();
} catch (Exception exc) {
throw new MCRException("The element is invalid because '" + e.getTag() + "' is invalid.",
exc);
}
}
}
/**
* This method put debug data to the logger (for the debug mode).
*/
public final void debug() {
if (LOGGER.isDebugEnabled()) {
for (MCRMetaElement sub : this) {
sub.debug();
}
}
}
@Override
public Iterator iterator() {
return metadataElements.iterator();
}
}