All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mycore.datamodel.metadata.MCRObjectService Maven / Gradle / Ivy

There is a newer version: 2024.05
Show newest version
/*
 * 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.Date;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

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.MCRUtils;
import org.mycore.common.config.MCRConfiguration2;
import org.mycore.datamodel.classifications2.MCRCategoryDAOFactory;
import org.mycore.datamodel.classifications2.MCRCategoryID;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

/**
 * This class implements all methods for handling MCRObject service data. 
 * The service data stores technical information that is no metadata. 
 * The service data holds three types of data, dates, flags and states. 
 * The flags are text strings and are optional.
 * 

* * The dates are represent by a date and a type. Two types are in service data * at every time and can't remove: *

    *
  • createdate - for the creating date of the object, this was set only one * time
  • *
  • modifydate - for the accepting date of the object, this was set at every * changes
  • *
* Other date types are optional, but as example in Dublin Core: *
    *
  • submitdate - for the submiting date of the object
  • *
  • acceptdate - for the accepting date of the object
  • *
  • validfromdate - for the date of the object, at this the object is valid * to use
  • *
  • validtodate - for the date of the object, at this the object is no more * valid to use
  • *
* * The state is optional and represented by a MyCoRe classification object. * * @author Jens Kupferschmidt * @author Matthias Eichner * @author Robert Stephan * @version $Revision$ $Date$ */ public class MCRObjectService { private static Logger LOGGER = LogManager.getLogger(); /** * constant for create date */ public static final String DATE_TYPE_CREATEDATE = "createdate"; /** * constant for modify date */ public static final String DATE_TYPE_MODIFYDATE = "modifydate"; /** * constant for create user */ public static final String FLAG_TYPE_CREATEDBY = "createdby"; /** * constant for modify user */ public static final String FLAG_TYPE_MODIFIEDBY = "modifiedby"; private final ArrayList dates; private final ArrayList rules; private final ArrayList flags; private MCRCategoryID state; /** * This is the constructor of the MCRObjectService class. All data are set * to null. */ public MCRObjectService() { dates = new ArrayList<>(); Date curTime = new Date(); MCRMetaISO8601Date d = new MCRMetaISO8601Date("servdate", DATE_TYPE_CREATEDATE, 0); d.setDate(curTime); dates.add(d); d = new MCRMetaISO8601Date("servdate", DATE_TYPE_MODIFYDATE, 0); d.setDate(curTime); dates.add(d); rules = new ArrayList<>(); flags = new ArrayList<>(); } /** * This method read the XML input stream part from a DOM part for the * structure data of the document. * * @param service * a list of relevant DOM elements for the metadata */ public final void setFromDOM(Element service) { // Date part Element servdates = service.getChild("servdates"); dates.clear(); if (servdates != null) { List dateList = servdates.getChildren(); for (Element dateElement : dateList) { String dateElementName = dateElement.getName(); if (!"servdate".equals(dateElementName)) { continue; } MCRMetaISO8601Date date = new MCRMetaISO8601Date(); date.setFromDOM(dateElement); setDate(date); } } // Rule part Element servacls = service.getChild("servacls"); if (servacls != null) { List ruleList = servacls.getChildren(); for (Element ruleElement : ruleList) { if (!ruleElement.getName().equals("servacl")) { continue; } MCRMetaAccessRule user = new MCRMetaAccessRule(); user.setFromDOM(ruleElement); rules.add(user); } } // Flag part Element flagsElement = service.getChild("servflags"); if (flagsElement != null) { List flagList = flagsElement.getChildren(); for (Element flagElement : flagList) { if (!flagElement.getName().equals("servflag")) { continue; } MCRMetaLangText flag = new MCRMetaLangText(); flag.setFromDOM(flagElement); flags.add(flag); } } Element statesElement = service.getChild("servstates"); if (statesElement != null) { List flagList = statesElement.getChildren(); for (Element stateElement : flagList) { if (!stateElement.getName().equals("servstate")) { continue; } MCRMetaClassification stateClass = new MCRMetaClassification(); stateClass.setFromDOM(stateElement); state = new MCRCategoryID(stateClass.getClassId(), stateClass.getCategId()); } } } /** * This method return the size of the date list. * * @return the size of the date list */ public final int getDateSize() { return dates.size(); } /** * Returns the dates. * * @return list of dates */ protected ArrayList getDates() { return dates; } /** * This method returns the status classification * * @return the status as MCRMetaClassification, * can return null * */ public final MCRCategoryID getState() { return state; } /** * This method get a date for a given type. If the type was not found, an * null was returned. * * @param type * the type of the date * @return the date as GregorianCalendar * * @see MCRObjectService#DATE_TYPE_CREATEDATE * @see MCRObjectService#DATE_TYPE_MODIFYDATE */ public final Date getDate(String type) { MCRMetaISO8601Date isoDate = getISO8601Date(type); if (isoDate == null) { return null; } return isoDate.getDate(); } private MCRMetaISO8601Date getISO8601Date(String type) { if (type == null || type.length() == 0) { return null; } return IntStream.range(0, dates.size()) .mapToObj(dates::get) .filter(d -> d.getType().equals(type)) .findAny() .orElse(null); } /** * This method set a date element in the dates list to a actual date value. * If the given type exists, the date was update. * * @param type * the type of the date */ public final void setDate(String type) { setDate(type, new Date()); } /** * This method set a date element in the dates list to a given date value. * If the given type exists, the date was update. * * @param type * the type of the date * @param date * set time to this Calendar * null means the actual date */ public final void setDate(String type, Date date) { MCRMetaISO8601Date d = getISO8601Date(type); //search date in ArrayList if (d == null) { d = new MCRMetaISO8601Date("servdate", type, 0); d.setDate(date); dates.add(d); } else { d.setDate(date); // alter date found in ArrayList } } /** * This method set a date element in the dates list to a given date value. * If the given type exists, the date was update. * * @param date * set time to this Calendar */ private void setDate(MCRMetaISO8601Date date) { MCRMetaISO8601Date d = getISO8601Date(date.getType()); //search date in ArrayList if (d == null) { dates.add(date); } else { d.setDate(date.getDate()); // alter date found in ArrayList } } /** * This method removes the date of the specified type from * the date list. * * @param type * a type as string */ public final void removeDate(String type) { if (DATE_TYPE_CREATEDATE.equals(type) || DATE_TYPE_MODIFYDATE.equals(type)) { LOGGER.error("Cannot delete built-in date: " + type); } else { MCRMetaISO8601Date d = getISO8601Date(type); if (d != null) { dates.remove(d); } } } /** * This method sets the status classification */ public final void setState(MCRCategoryID state) { if (state == null) { this.state = state; } else { if (MCRCategoryDAOFactory.getInstance().exist(state)) { this.state = state; } else { LOGGER.warn("Error at setting servstate classification.", new MCRException("The category " + state + " does not exist.")); } } } /** * This method sets the status classification with the given string as categid * and the default classid ('state') */ public final void setState(String state) { if (state == null) { this.state = null; } else { MCRCategoryID categState = new MCRCategoryID( MCRConfiguration2.getString("MCR.Metadata.Service.State.Classification.ID").orElse("state"), state); setState(categState); } } /** * This method removes the current state */ public final void removeState() { this.state = null; } /** * This method add a flag to the flag list. * * @param value - * the new flag as string */ public final void addFlag(String value) { addFlag(null, value); } /** * This method adds a flag to the flag list. * * @param type * a type as string * @param value * the new flag value as string */ public final void addFlag(String type, String value) { String lType = MCRUtils.filterTrimmedNotEmpty(type).orElse(null); MCRUtils.filterTrimmedNotEmpty(value) .map(flagValue -> new MCRMetaLangText("servflag", null, lType, 0, null, flagValue)) .ifPresent(flags::add); } /** * This method get all flags from the flag list as a string. * * @return the flags string */ public final String getFlags() { StringBuilder sb = new StringBuilder(); for (MCRMetaLangText flag : flags) { sb.append(flag.getText()).append(" "); } return sb.toString(); } /** * Returns the flags as list. * * @return flags as list */ protected final List getFlagsAsList() { return flags; } /** * This method returns all flag values of the specified type. * * @param type * a type as string. * @return a list of flag values */ protected final ArrayList getFlagsAsMCRMetaLangText(String type) { return flags.stream() .filter(metaLangText -> type.equals(metaLangText.getType())) .collect(Collectors.toCollection(ArrayList::new)); } /** * This method returns all flag values of the specified type. * * @param type * a type as string. * @return a list of flag values */ public final ArrayList getFlags(String type) { return getFlagsAsMCRMetaLangText(type).stream() .map(MCRMetaLangText::getText) .collect(Collectors.toCollection(ArrayList::new)); } /** * This method return the size of the flag list. * * @return the size of the flag list */ public final int getFlagSize() { return flags.size(); } /** * This method get a single flag from the flag list as a string. * * @exception IndexOutOfBoundsException * throw this exception, if the index is false * @return a flag string */ public final String getFlag(int index) throws IndexOutOfBoundsException { if (index < 0 || index > flags.size()) { throw new IndexOutOfBoundsException("Index error in getFlag."); } return flags.get(index).getText(); } /** * This method gets a single flag type from the flag list as a string. * * @exception IndexOutOfBoundsException * throw this exception, if the index is false * @return a flag type */ public final String getFlagType(int index) throws IndexOutOfBoundsException { if (index < 0 || index > flags.size()) { throw new IndexOutOfBoundsException("Index error in getFlagType."); } return flags.get(index).getType(); } /** * This method return a boolean value if the given flag is set or not. * * @param value * a searched flag * @return true if the flag was found in the list */ public final boolean isFlagSet(String value) { return MCRUtils.filterTrimmedNotEmpty(value) .map(flagValue -> flags.stream().anyMatch(flag -> flag.getText().equals(flagValue))) .orElse(false); } /** * Proves if the type is set in the flag list. * @param type * a type as string * @return true if the flag list contains flags with this type, * otherwise false */ public final boolean isFlagTypeSet(String type) { return MCRUtils.filterTrimmedNotEmpty(type) .map(flagType -> flags.stream().anyMatch(flag -> flag.getType().equals(flagType))) .orElse(false); } /** * This method remove a flag from the flag list. * * @param index * a index in the list * @exception IndexOutOfBoundsException * throw this exception, if the index is false */ public final void removeFlag(int index) throws IndexOutOfBoundsException { if (index < 0 || index > flags.size()) { throw new IndexOutOfBoundsException("Index error in removeFlag."); } flags.remove(index); } /** * This method removes all flags of the specified type from * the flag list. * * @param type * a type as string */ public final void removeFlags(String type) { ArrayList internalList = getFlagsAsMCRMetaLangText(type); flags.removeAll(internalList); } /** * This method set a flag in the flag list. * * @param index * a index in the list * @param value * the value of a flag as string * @exception IndexOutOfBoundsException * throw this exception, if the index is false */ public final void replaceFlag(int index, String value) throws IndexOutOfBoundsException { MCRUtils.filterTrimmedNotEmpty(value) .ifPresent(flagValue -> updateFlag(index, flag -> flag.setText(value))); } private void updateFlag(int index, Consumer flagUpdater) { MCRMetaLangText flag = flags.get(index); flagUpdater.accept(flag); } /** * This method sets the type value of a flag at the specified index. * * @param index * a index in the list * @param value * the value of a flag as string * @exception IndexOutOfBoundsException * throw this exception, if the index is false */ public final void replaceFlagType(int index, String value) throws IndexOutOfBoundsException { MCRUtils.filterTrimmedNotEmpty(value) .ifPresent(flagValue -> updateFlag(index, flag -> flag.setType(value))); } /** * This method add a rule to the rules list. * * @param permission - * the new permission as string * @param condition - * the new rule as JDOM tree Element */ public final void addRule(String permission, Element condition) { if (condition == null) { return; } MCRUtils.filterTrimmedNotEmpty(permission) .filter(p -> getRuleIndex(p) == -1) .map(p -> new MCRMetaAccessRule("servacl", null, 0, p, condition)) .ifPresent(rules::add); } /** * This method return the size of the rules list. * * @return the size of the rules list */ public final int getRulesSize() { return rules.size(); } /** * This method return the index of a permission in the rules list. * * @return the index of a permission in the rules list */ public final int getRuleIndex(String permission) { int notFound = -1; if (permission == null || permission.trim().length() == 0) { return notFound; } return IntStream.range(0, rules.size()) .filter(i -> rules.get(i).getPermission().equals(permission)) .findAny() .orElse(notFound); } /** * This method get a single rule from the rules list as a JDOM Element. * * @exception IndexOutOfBoundsException * throw this exception, if the index is false * @return a the MCRMetaAccessRule instance */ public final MCRMetaAccessRule getRule(int index) throws IndexOutOfBoundsException { if (index < 0 || index > rules.size()) { throw new IndexOutOfBoundsException("Index error in getRule."); } return rules.get(index); } /** * This method get a single permission name of rule from the rules list as a * string. * * @exception IndexOutOfBoundsException * throw this exception, if the index is false * @return a rule permission string */ public final String getRulePermission(int index) throws IndexOutOfBoundsException { if (index < 0 || index > rules.size()) { throw new IndexOutOfBoundsException("Index error in getRulePermission."); } return rules.get(index).getPermission(); } /** * This method remove a rule from the rules list. * * @param index * a index in the list * @exception IndexOutOfBoundsException * throw this exception, if the index is false */ public final void removeRule(int index) throws IndexOutOfBoundsException { if (index < 0 || index > rules.size()) { throw new IndexOutOfBoundsException("Index error in removeRule."); } rules.remove(index); } /** * Returns the rules. * * @return list of rules */ protected final ArrayList getRules() { return rules; } /** * This method create a XML stream for all structure data. * * @exception MCRException * if the content of this class is not valid * @return a JDOM Element with the XML data of the structure data part */ public final Element createXML() throws MCRException { try { validate(); } catch (MCRException exc) { throw new MCRException("The content is not valid.", exc); } Element elm = new Element("service"); if (dates.size() != 0) { Element elmm = new Element("servdates"); elmm.setAttribute("class", "MCRMetaISO8601Date"); for (MCRMetaISO8601Date date : dates) { elmm.addContent(date.createXML()); } elm.addContent(elmm); } if (rules.size() != 0) { Element elmm = new Element("servacls"); elmm.setAttribute("class", "MCRMetaAccessRule"); for (MCRMetaAccessRule rule : rules) { elmm.addContent(rule.createXML()); } elm.addContent(elmm); } if (flags.size() != 0) { Element elmm = new Element("servflags"); elmm.setAttribute("class", "MCRMetaLangText"); for (MCRMetaLangText flag : flags) { elmm.addContent(flag.createXML()); } elm.addContent(elmm); } if (state != null) { Element elmm = new Element("servstates"); elmm.setAttribute("class", "MCRMetaClassification"); MCRMetaClassification stateClass = new MCRMetaClassification("servstate", 0, null, state); elmm.addContent(stateClass.createXML()); elm.addContent(elmm); } return elm; } /** * Creates the JSON representation of this service. * *
     *   {
     *      dates: [
     *          {@link MCRMetaISO8601Date#createJSON()},
     *          ...
     *      ],
     *      rules: [
     *          {@link MCRMetaAccessRule#createJSON()},
     *          ...
     *      ],
     *      flags: [
     *          {@link MCRMetaLangText#createJSON()},
     *          ...
     *      ],
     *      state: {
     *          
     *      }
     *   }
     * 
* * @return a json gson representation of this service */ public final JsonObject createJSON() { JsonObject service = new JsonObject(); // dates if (!getDates().isEmpty()) { JsonObject dates = new JsonObject(); getDates() .stream() .forEachOrdered(date -> { JsonObject jsonDate = date.createJSON(); jsonDate.remove("type"); dates.add(date.getType(), jsonDate); }); service.add("dates", dates); } // rules if (!getRules().isEmpty()) { JsonArray rules = new JsonArray(); getRules() .stream() .map(MCRMetaAccessRule::createJSON) .forEachOrdered(rules::add); service.add("rules", rules); } // flags if (!getFlags().isEmpty()) { JsonArray flags = new JsonArray(); getFlagsAsList() .stream() .map(MCRMetaLangText::createJSON) .forEachOrdered(flags::add); service.add("flags", flags); } // state Optional.ofNullable(getState()).ifPresent(stateId -> { JsonObject state = new JsonObject(); if (stateId.getID() != null) { state.addProperty("id", stateId.getID()); } state.addProperty("rootId", stateId.getRootID()); }); return service; } /** * This method check the validation of the content of this class. The method * returns true if *
    *
  • the date value of "createdate" is not null or empty *
  • the date value of "modifydate" is not null or empty *
* otherwise the method return false * * @return a boolean value */ public final boolean isValid() { try { validate(); return true; } catch (MCRException exc) { LOGGER.warn("The part is invalid."); } return false; } /** * Validates the content of this class. This method throws an exception if: *
    *
  • the date value of "createdate" is not null or empty
  • *
  • the date value of "modifydate" is not null or empty
  • *
* * @throws MCRException the content is invalid */ public void validate() { // TODO: this makes no sense - there is nothing to validate if (getISO8601Date(DATE_TYPE_CREATEDATE) == null) { setDate(DATE_TYPE_CREATEDATE); } if (getISO8601Date(DATE_TYPE_MODIFYDATE) == null) { setDate(DATE_TYPE_MODIFYDATE); } } /** * This method returns the index for the given flag value. * * @param value * the value of a flag as string * @return the index number or -1 if the value was not found */ public final int getFlagIndex(String value) { return MCRUtils.filterTrimmedNotEmpty(value) .map(v -> { for (int i = 0; i < flags.size(); i++) { if (flags.get(i).getText().equals(v)) { return i; } } return -1; }) .orElse(-1); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy