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

eu.toop.edm.EDMRequest Maven / Gradle / Ivy

/**
 * This work is protected under copyrights held by the members of the
 * TOOP Project Consortium as indicated at
 * http://wiki.ds.unipi.gr/display/TOOP/Contributors
 * (c) 2018-2021. All rights reserved.
 *
 * This work is dual licensed under Apache License, Version 2.0
 * and the EUPL 1.2.
 *
 *  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *  = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
 *
 * Licensed under the EUPL, Version 1.2 or – as soon they will be approved
 * by the European Commission - subsequent versions of the EUPL
 * (the "Licence");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 *
 *         https://joinup.ec.europa.eu/software/page/eupl
 */
package eu.toop.edm;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.OverridingMethodsMustInvokeSuper;

import org.w3c.dom.Node;

import com.helger.commons.ValueEnforcer;
import com.helger.commons.annotation.Nonempty;
import com.helger.commons.annotation.ReturnsMutableCopy;
import com.helger.commons.annotation.ReturnsMutableObject;
import com.helger.commons.collection.impl.CommonsArrayList;
import com.helger.commons.collection.impl.CommonsHashSet;
import com.helger.commons.collection.impl.CommonsLinkedHashMap;
import com.helger.commons.collection.impl.CommonsLinkedHashSet;
import com.helger.commons.collection.impl.ICommonsList;
import com.helger.commons.collection.impl.ICommonsOrderedMap;
import com.helger.commons.collection.impl.ICommonsOrderedSet;
import com.helger.commons.collection.impl.ICommonsSet;
import com.helger.commons.datetime.PDTFactory;
import com.helger.commons.equals.EqualsHelper;
import com.helger.commons.hashcode.HashCodeGenerator;
import com.helger.commons.string.StringHelper;
import com.helger.commons.string.ToStringGenerator;
import com.helger.commons.traits.IGenericImplTrait;

import eu.toop.edm.jaxb.cccev.CCCEVConceptType;
import eu.toop.edm.jaxb.cccev.CCCEVRequirementType;
import eu.toop.edm.jaxb.cv.agent.AgentType;
import eu.toop.edm.jaxb.dcatap.DCatAPDistributionType;
import eu.toop.edm.jaxb.w3.cv.ac.CoreBusinessType;
import eu.toop.edm.jaxb.w3.cv.ac.CorePersonType;
import eu.toop.edm.model.AgentPojo;
import eu.toop.edm.model.BusinessPojo;
import eu.toop.edm.model.ConceptPojo;
import eu.toop.edm.model.DistributionPojo;
import eu.toop.edm.model.EToopLanguageCode;
import eu.toop.edm.model.EToopQueryDefinitionType;
import eu.toop.edm.model.EToopResponseOptionType;
import eu.toop.edm.model.PersonPojo;
import eu.toop.edm.request.EDMRequestPayloadConcepts;
import eu.toop.edm.request.EDMRequestPayloadDistribution;
import eu.toop.edm.request.EDMRequestPayloadDocumentID;
import eu.toop.edm.request.IEDMRequestPayloadProvider;
import eu.toop.edm.slot.SlotAuthorizedRepresentative;
import eu.toop.edm.slot.SlotConceptRequestList;
import eu.toop.edm.slot.SlotConsentToken;
import eu.toop.edm.slot.SlotDataConsumer;
import eu.toop.edm.slot.SlotDataSubjectLegalPerson;
import eu.toop.edm.slot.SlotDataSubjectNaturalPerson;
import eu.toop.edm.slot.SlotDatasetIdentifier;
import eu.toop.edm.slot.SlotDistributionRequestList;
import eu.toop.edm.slot.SlotFullfillingRequirements;
import eu.toop.edm.slot.SlotIssueDateTime;
import eu.toop.edm.slot.SlotProcedure;
import eu.toop.edm.slot.SlotSpecificationIdentifier;
import eu.toop.edm.xml.IJAXBVersatileReader;
import eu.toop.edm.xml.IVersatileWriter;
import eu.toop.edm.xml.JAXBVersatileReader;
import eu.toop.edm.xml.JAXBVersatileWriter;
import eu.toop.edm.xml.cagv.AgentMarshaller;
import eu.toop.edm.xml.cagv.CCAGV;
import eu.toop.edm.xml.cccev.ConceptMarshaller;
import eu.toop.edm.xml.cccev.RequirementMarshaller;
import eu.toop.edm.xml.cv.BusinessMarshaller;
import eu.toop.edm.xml.cv.PersonMarshaller;
import eu.toop.edm.xml.dcatap.DistributionMarshaller;
import eu.toop.regrep.RegRep4Reader;
import eu.toop.regrep.RegRep4Writer;
import eu.toop.regrep.RegRepHelper;
import eu.toop.regrep.query.QueryRequest;
import eu.toop.regrep.query.ResponseOptionType;
import eu.toop.regrep.rim.AnyValueType;
import eu.toop.regrep.rim.CollectionValueType;
import eu.toop.regrep.rim.DateTimeValueType;
import eu.toop.regrep.rim.InternationalStringType;
import eu.toop.regrep.rim.InternationalStringValueType;
import eu.toop.regrep.rim.LocalizedStringType;
import eu.toop.regrep.rim.QueryType;
import eu.toop.regrep.rim.SlotType;
import eu.toop.regrep.rim.StringValueType;
import eu.toop.regrep.rim.ValueType;
import eu.toop.regrep.slot.ISlotProvider;
import eu.toop.regrep.slot.SlotHelper;
import eu.toop.regrep.slot.predefined.SlotId;

/**
 * This class contains the data model for a single TOOP EDM Request. It requires
 * at least the following fields:
 * 
    *
  • QueryDefinition - Concept or Document query?
  • *
  • Request ID - the internal ID of the request that must be part of the * response. Can be a UUID.
  • *
  • Specification Identifier - must be the value * {@link CToopEDM#SPECIFICATION_IDENTIFIER_TOOP_EDM_V21}.
  • *
  • Issue date time - when the request was created. Ideally in UTC.
  • *
  • Data Consumer - the basic infos of the DC
  • *
  • Data Subject - either as Legal Person or as Natural Person, but not * both.
  • *
  • If it is a "ConceptQuery" the request Concepts must be provided.
  • *
  • If it is a "DocumentQuery" the request distribution must be * provided.
  • *
  • If it is a "ObjectReference" the request Document ID must be * provided.
  • *
* It is recommended to use the builder*() methods to create the * EDM request using the builder pattern with a fluent API. * * @author Philip Helger * @author Konstantinos Douloudis */ public class EDMRequest implements IEDMTopLevelObject { private static final ICommonsOrderedSet TOP_LEVEL_SLOTS = new CommonsLinkedHashSet <> (SlotSpecificationIdentifier.NAME, SlotIssueDateTime.NAME, SlotProcedure.NAME, SlotFullfillingRequirements.NAME, SlotConsentToken.NAME, SlotDatasetIdentifier.NAME, SlotDataConsumer.NAME); private final EToopQueryDefinitionType m_eQueryDefinition; private final String m_sRequestID; private final EToopResponseOptionType m_eResponseOption; private final String m_sSpecificationIdentifier; private final LocalDateTime m_aIssueDateTime; private final InternationalStringType m_aProcedure; private final ICommonsList m_aFullfillingRequirements = new CommonsArrayList <> (); private final AgentPojo m_aDataConsumer; private final String m_sConsentToken; private final String m_sDatasetIdentifier; private final BusinessPojo m_aDataSubjectLegalPerson; private final PersonPojo m_aDataSubjectNaturalPerson; private final PersonPojo m_aAuthorizedRepresentative; private final IEDMRequestPayloadProvider m_aPayloadProvider; protected EDMRequest (@Nonnull final EToopQueryDefinitionType eQueryDefinition, @Nonnull @Nonempty final String sRequestID, @Nonnull final EToopResponseOptionType eResponseOption, @Nonnull @Nonempty final String sSpecificationIdentifier, @Nonnull final LocalDateTime aIssueDateTime, @Nullable final InternationalStringType aProcedure, @Nullable final ICommonsList aFullfillingRequirements, @Nonnull final AgentPojo aDataConsumer, @Nullable final String sConsentToken, @Nullable final String sDatasetIdentifier, @Nullable final BusinessPojo aDataSubjectLegalPerson, @Nullable final PersonPojo aDataSubjectNaturalPerson, @Nullable final PersonPojo aAuthorizedRepresentative, @Nonnull final IEDMRequestPayloadProvider aRPP) { ValueEnforcer.notNull (eQueryDefinition, "QueryDefinition"); ValueEnforcer.notNull (eResponseOption, "ResponseOption"); ValueEnforcer.notEmpty (sRequestID, "RequestID"); ValueEnforcer.notEmpty (sSpecificationIdentifier, "SpecificationIdentifier"); ValueEnforcer.notNull (aIssueDateTime, "IssueDateTime"); ValueEnforcer.noNullValue (aFullfillingRequirements, "FullfillingRequirements"); ValueEnforcer.notNull (aDataConsumer, "DataConsumer"); if (!eQueryDefinition.isDataSujectOptional ()) ValueEnforcer.isFalse (aDataSubjectLegalPerson == null && aDataSubjectNaturalPerson == null, "A DataSubject must be set"); ValueEnforcer.isFalse (aDataSubjectLegalPerson != null && aDataSubjectNaturalPerson != null, "Not more than one DataSubject must be set"); ValueEnforcer.notNull (aRPP, "RequestPayloadProvider"); m_eQueryDefinition = eQueryDefinition; m_sRequestID = sRequestID; m_eResponseOption = eResponseOption; m_sSpecificationIdentifier = sSpecificationIdentifier; m_aIssueDateTime = aIssueDateTime; m_aProcedure = aProcedure; if (aFullfillingRequirements != null) m_aFullfillingRequirements.addAll (aFullfillingRequirements); m_aDataConsumer = aDataConsumer; m_sConsentToken = sConsentToken; m_sDatasetIdentifier = sDatasetIdentifier; m_aDataSubjectLegalPerson = aDataSubjectLegalPerson; m_aDataSubjectNaturalPerson = aDataSubjectNaturalPerson; m_aAuthorizedRepresentative = aAuthorizedRepresentative; m_aPayloadProvider = aRPP; } /** * @return The query definition type as provided in the constructor. Never * null. */ @Nonnull public final EToopQueryDefinitionType getQueryDefinition () { return m_eQueryDefinition; } /** * @return The TOOP internal request ID. Neither null nor empty. */ @Nonnull @Nonempty public final String getRequestID () { return m_sRequestID; } /** * @return The response option to be used. Never null. */ @Nonnull public final EToopResponseOptionType getResponseOption () { return m_eResponseOption; } /** * @return The specification identifier that identifies the data model in use. * See {@link CToopEDM#SPECIFICATION_IDENTIFIER_TOOP_EDM_V21} for the * current one. */ @Nonnull @Nonempty public final String getSpecificationIdentifier () { return m_sSpecificationIdentifier; } /** * @return The local date and time when the EDM request was created. Never * null. */ @Nonnull public final LocalDateTime getIssueDateTime () { return m_aIssueDateTime; } @Nullable public final InternationalStringType getProcedure () { return m_aProcedure; } @Nonnull @ReturnsMutableObject public final List fullfillingRequirements () { return m_aFullfillingRequirements; } @Nonnull @ReturnsMutableCopy public final List getAllFullfillingRequirements () { return m_aFullfillingRequirements.getClone (); } @Nonnull public final AgentPojo getDataConsumer () { return m_aDataConsumer; } @Nullable public final String getConsentToken () { return m_sConsentToken; } @Nullable public final String getDatasetIdentifier () { return m_sDatasetIdentifier; } @Nullable public final BusinessPojo getDataSubjectLegalPerson () { return m_aDataSubjectLegalPerson; } @Nullable public final PersonPojo getDataSubjectNaturalPerson () { return m_aDataSubjectNaturalPerson; } @Nullable public final PersonPojo getAuthorizedRepresentative () { return m_aAuthorizedRepresentative; } /** * @return The request payload provider. Never null. This is one * of {@link eu.toop.edm.request.IEDMRequestPayloadConcepts}, * {@link eu.toop.edm.request.IEDMRequestPayloadDistribution} or * {@link eu.toop.edm.request.IEDMRequestPayloadDocumentID}. */ @Nonnull public final IEDMRequestPayloadProvider getPayloadProvider () { return m_aPayloadProvider; } @Nonnull private QueryRequest _createQueryRequest (@Nonnull final ICommonsList aProviders) { ValueEnforcer.notNull (m_eQueryDefinition, "QueryDefinition"); ValueEnforcer.notEmpty (m_sRequestID, "RequestID"); ValueEnforcer.noNullValue (aProviders, "Providers"); // Maintain original order final ICommonsOrderedMap aProviderMap = new CommonsLinkedHashMap <> (); for (final ISlotProvider aItem : aProviders) { final String sName = aItem.getName (); if (aProviderMap.containsKey (sName)) throw new IllegalArgumentException ("A slot provider for name '" + sName + "' is already present"); aProviderMap.put (sName, aItem); } final QueryRequest ret = RegRepHelper.createEmptyQueryRequest (); ret.setId (m_sRequestID); ret.getResponseOption ().setReturnType (m_eResponseOption.getID ()); // All top-level slots outside of query for (final String sTopLevel : TOP_LEVEL_SLOTS) { final ISlotProvider aSP = aProviderMap.get (sTopLevel); if (aSP != null) ret.addSlot (aSP.createSlot ()); } { final QueryType aQuery = new QueryType (); aQuery.setQueryDefinition (m_eQueryDefinition.getID ()); // All slots inside of query for (final Map.Entry aEntry : aProviderMap.entrySet ()) if (!TOP_LEVEL_SLOTS.contains (aEntry.getKey ())) aQuery.addSlot (aEntry.getValue ().createSlot ()); ret.setQuery (aQuery); } return ret; } @Nonnull public QueryRequest getAsQueryRequest () { final ICommonsList aSlots = new CommonsArrayList <> (); // Top-level slots if (m_sSpecificationIdentifier != null) aSlots.add (new SlotSpecificationIdentifier (m_sSpecificationIdentifier)); if (m_aIssueDateTime != null) aSlots.add (new SlotIssueDateTime (m_aIssueDateTime)); if (m_aProcedure != null) aSlots.add (new SlotProcedure (m_aProcedure)); if (m_aFullfillingRequirements.isNotEmpty ()) aSlots.add (new SlotFullfillingRequirements (m_aFullfillingRequirements)); if (m_sConsentToken != null) aSlots.add (new SlotConsentToken (m_sConsentToken)); if (m_sDatasetIdentifier != null) aSlots.add (new SlotDatasetIdentifier (m_sDatasetIdentifier)); if (m_aDataConsumer != null) aSlots.add (new SlotDataConsumer (m_aDataConsumer)); // Commons Query slots if (m_aDataSubjectLegalPerson != null) aSlots.add (new SlotDataSubjectLegalPerson (m_aDataSubjectLegalPerson)); if (m_aDataSubjectNaturalPerson != null) aSlots.add (new SlotDataSubjectNaturalPerson (m_aDataSubjectNaturalPerson)); if (m_aAuthorizedRepresentative != null) aSlots.add (new SlotAuthorizedRepresentative (m_aAuthorizedRepresentative)); // Request payload slot aSlots.add (m_aPayloadProvider.getAsSlotProvider ()); return _createQueryRequest (aSlots); } @Nonnull public IVersatileWriter getWriter () { return new JAXBVersatileWriter <> (getAsQueryRequest (), RegRep4Writer.queryRequest (CCAGV.XSDS).setFormattedOutput (true)); } @Nonnull public static IJAXBVersatileReader reader () { return new JAXBVersatileReader <> (RegRep4Reader.queryRequest (CCAGV.XSDS), EDMRequest::create); } @Override public boolean equals (final Object o) { if (this == o) return true; if (o == null || getClass () != o.getClass ()) return false; final EDMRequest rhs = (EDMRequest) o; return EqualsHelper.equals (m_eQueryDefinition, rhs.m_eQueryDefinition) && EqualsHelper.equals (m_eResponseOption, rhs.m_eResponseOption) && EqualsHelper.equals (m_sRequestID, rhs.m_sRequestID) && EqualsHelper.equals (m_sSpecificationIdentifier, rhs.m_sSpecificationIdentifier) && EqualsHelper.equals (m_aIssueDateTime, rhs.m_aIssueDateTime) && EqualsHelper.equals (m_aProcedure, rhs.m_aProcedure) && EqualsHelper.equals (m_aFullfillingRequirements, rhs.m_aFullfillingRequirements) && EqualsHelper.equals (m_aDataConsumer, rhs.m_aDataConsumer) && EqualsHelper.equals (m_sConsentToken, rhs.m_sConsentToken) && EqualsHelper.equals (m_sDatasetIdentifier, rhs.m_sDatasetIdentifier) && EqualsHelper.equals (m_aDataSubjectLegalPerson, rhs.m_aDataSubjectLegalPerson) && EqualsHelper.equals (m_aDataSubjectNaturalPerson, rhs.m_aDataSubjectNaturalPerson) && EqualsHelper.equals (m_aAuthorizedRepresentative, rhs.m_aAuthorizedRepresentative) && EqualsHelper.equals (m_aPayloadProvider, rhs.m_aPayloadProvider); } @Override public int hashCode () { return new HashCodeGenerator (this).append (m_eQueryDefinition) .append (m_eResponseOption) .append (m_sRequestID) .append (m_sSpecificationIdentifier) .append (m_aIssueDateTime) .append (m_aProcedure) .append (m_aFullfillingRequirements) .append (m_aDataConsumer) .append (m_sConsentToken) .append (m_sDatasetIdentifier) .append (m_aDataSubjectLegalPerson) .append (m_aDataSubjectNaturalPerson) .append (m_aAuthorizedRepresentative) .append (m_aPayloadProvider) .getHashCode (); } @Override public String toString () { return new ToStringGenerator (this).append ("QueryDefinition", m_eQueryDefinition) .append ("ResponseOption", m_eResponseOption) .append ("RequestID", m_sRequestID) .append ("SpecificationIdentifier", m_sSpecificationIdentifier) .append ("IssueDateTime", m_aIssueDateTime) .append ("Procedure", m_aProcedure) .append ("FullfillingRequirements", m_aFullfillingRequirements) .append ("DataConsumer", m_aDataConsumer) .append ("ConsentToken", m_sConsentToken) .append ("DatasetIdentifier", m_sDatasetIdentifier) .append ("DataSubjectLegalPerson", m_aDataSubjectLegalPerson) .append ("DataSubjectNaturalPerson", m_aDataSubjectNaturalPerson) .append ("AuthorizedRepresentative", m_aAuthorizedRepresentative) .append ("RequestPayloadProvider", m_aPayloadProvider) .getToString (); } @Nonnull public static BuilderConcept builderConcept () { return new BuilderConcept ().specificationIdentifier (CToopEDM.SPECIFICATION_IDENTIFIER_TOOP_EDM_V21) .responseOption (EToopResponseOptionType.INLINE); } @Nonnull public static BuilderDocumentsByDistribution builderDocumentsByDistribution () { return new BuilderDocumentsByDistribution ().specificationIdentifier (CToopEDM.SPECIFICATION_IDENTIFIER_TOOP_EDM_V21) .responseOption (EToopResponseOptionType.INLINE); } @Nonnull public static BuilderDocumentsByDistribution builderDocumentReferencesByDistribution () { return new BuilderDocumentsByDistribution ().specificationIdentifier (CToopEDM.SPECIFICATION_IDENTIFIER_TOOP_EDM_V21) .responseOption (EToopResponseOptionType.REFERENCE); } /** * @return A new builder for an EDM Request that is request with a an ID only. */ @Nonnull public static BuilderDocumentByID builderDocumentByID () { return new BuilderDocumentByID ().specificationIdentifier (CToopEDM.SPECIFICATION_IDENTIFIER_TOOP_EDM_V21) .responseOption (EToopResponseOptionType.INLINE); } /** * Generic Builder for an EDM request * * @author Philip Helger * @param * The implementation class of this class */ public abstract static class AbstractBuilder > implements IGenericImplTrait { protected final EToopQueryDefinitionType m_eQueryDefinition; protected String m_sRequestID; protected EToopResponseOptionType m_eResponseOption; protected String m_sSpecificationIdentifier; protected LocalDateTime m_aIssueDateTime; protected InternationalStringType m_aProcedure; protected final ICommonsList m_aFullfillingRequirements = new CommonsArrayList <> (); protected AgentPojo m_aDataConsumer; protected String m_sConsentToken; protected String m_sDatasetIdentifier; protected BusinessPojo m_aDataSubjectLegalPerson; protected PersonPojo m_aDataSubjectNaturalPerson; protected PersonPojo m_aAuthorizedRepresentative; protected AbstractBuilder (@Nonnull final EToopQueryDefinitionType e) { ValueEnforcer.notNull (e, "QueryDefinitionType"); m_eQueryDefinition = e; } @Nonnull public final IMPLTYPE randomID () { return id (UUID.randomUUID ()); } @Nonnull public final IMPLTYPE id (@Nullable final UUID a) { return id (a == null ? null : a.toString ()); } @Nonnull public final IMPLTYPE id (@Nullable final String s) { m_sRequestID = s; return thisAsT (); } @Nonnull public final IMPLTYPE responseOption (@Nullable final EToopResponseOptionType e) { m_eResponseOption = e; return thisAsT (); } @Nonnull public final IMPLTYPE specificationIdentifier (@Nullable final String s) { m_sSpecificationIdentifier = s; return thisAsT (); } @Nonnull public final IMPLTYPE issueDateTimeNow () { return issueDateTime (PDTFactory.getCurrentLocalDateTime ()); } @Nonnull public final IMPLTYPE issueDateTime (@Nullable final LocalDateTime a) { m_aIssueDateTime = a == null ? null : a.truncatedTo (ChronoUnit.MILLIS); return thisAsT (); } @Nonnull public final IMPLTYPE procedure (@Nullable final LocalizedStringType... a) { return procedure (a == null ? null : SlotHelper.createInternationalStringType (a)); } @Nonnull public final IMPLTYPE procedure (@Nonnull final Locale aLocale, @Nonnull final String sText) { return procedure (SlotHelper.createLocalizedString (aLocale, sText)); } @Nonnull public final IMPLTYPE procedure (@Nonnull @Nonempty final String sLanguage, @Nonnull final String sText) { return procedure (SlotHelper.createLocalizedString (sLanguage, sText)); } @Nonnull public final IMPLTYPE procedure (@Nonnull final EToopLanguageCode eLanguage, @Nonnull final String sText) { return procedure (SlotHelper.createLocalizedString (eLanguage.getID (), sText)); } @Nonnull public final IMPLTYPE procedure (@Nullable final Map a) { return procedure (a == null ? null : SlotHelper.createInternationalStringType (a)); } @Nonnull public final IMPLTYPE procedure (@Nullable final InternationalStringType a) { m_aProcedure = a; return thisAsT (); } @Nonnull public final IMPLTYPE addFullfillingRequirement (@Nullable final CCCEVRequirementType a) { if (a != null) m_aFullfillingRequirements.add (a); return thisAsT (); } @Nonnull public final IMPLTYPE fullfillingRequirement (@Nullable final CCCEVRequirementType a) { if (a != null) m_aFullfillingRequirements.set (a); else m_aFullfillingRequirements.clear (); return thisAsT (); } @Nonnull public final IMPLTYPE fullfillingRequirements (@Nullable final CCCEVRequirementType... a) { m_aFullfillingRequirements.setAll (a); return thisAsT (); } @Nonnull public final IMPLTYPE fullfillingRequirements (@Nullable final Iterable a) { m_aFullfillingRequirements.setAll (a); return thisAsT (); } @Nonnull public final IMPLTYPE fullfillingRequirements (@Nullable final Iterable a, @Nonnull final Function aMapper) { m_aFullfillingRequirements.setAllMapped (a, aMapper); return thisAsT (); } @Nonnull public final IMPLTYPE consentToken (@Nullable final String s) { m_sConsentToken = s; return thisAsT (); } @Nonnull public final IMPLTYPE datasetIdentifier (@Nullable final String s) { m_sDatasetIdentifier = s; return thisAsT (); } @Nonnull public final IMPLTYPE dataConsumer (@Nullable final Consumer a) { if (a != null) { final AgentPojo.Builder aBuilder = AgentPojo.builder (); a.accept (aBuilder); dataConsumer (aBuilder.build ()); } return thisAsT (); } @Nonnull public final IMPLTYPE dataConsumer (@Nullable final AgentType a) { return dataConsumer (a == null ? null : AgentPojo.builder (a)); } @Nonnull public final IMPLTYPE dataConsumer (@Nullable final AgentPojo.Builder a) { return dataConsumer (a == null ? null : a.build ()); } @Nonnull public final IMPLTYPE dataConsumer (@Nullable final AgentPojo a) { m_aDataConsumer = a; return thisAsT (); } /** * Set a legal person as data subject. This method nulls an eventually set * natural person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubjectBusiness (@Nullable final Consumer a) { if (a != null) { final BusinessPojo.Builder aBuilder = BusinessPojo.builder (); a.accept (aBuilder); dataSubject (aBuilder.build ()); } return thisAsT (); } /** * Set a legal person as data subject. This method nulls an eventually set * natural person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubject (@Nullable final CoreBusinessType a) { return dataSubject (a == null ? null : BusinessPojo.builder (a)); } /** * Set a legal person as data subject. This method nulls an eventually set * natural person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubject (@Nullable final BusinessPojo.Builder a) { return dataSubject (a == null ? null : a.build ()); } /** * Set a legal person as data subject. This method nulls an eventually set * natural person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubject (@Nullable final BusinessPojo a) { m_aDataSubjectLegalPerson = a; m_aDataSubjectNaturalPerson = null; return thisAsT (); } /** * Set a natural person as data subject. This method nulls an eventually set * legal person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubjectPerson (@Nullable final Consumer a) { if (a != null) { final PersonPojo.Builder aBuilder = PersonPojo.builder (); a.accept (aBuilder); dataSubject (aBuilder.build ()); } return thisAsT (); } /** * Set a natural person as data subject. This method nulls an eventually set * legal person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubject (@Nullable final CorePersonType a) { return dataSubject (a == null ? null : PersonPojo.builder (a)); } /** * Set a natural person as data subject. This method nulls an eventually set * legal person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubject (@Nullable final PersonPojo.Builder a) { return dataSubject (a == null ? null : a.build ()); } /** * Set a natural person as data subject. This method nulls an eventually set * legal person data subject. * * @param a * The value to set. May be null. * @return this for chaining. */ @Nonnull public final IMPLTYPE dataSubject (@Nullable final PersonPojo a) { m_aDataSubjectLegalPerson = null; m_aDataSubjectNaturalPerson = a; return thisAsT (); } @Nonnull public final IMPLTYPE authorizedRepresentative (@Nullable final Consumer a) { if (a != null) { final PersonPojo.Builder aBuilder = PersonPojo.builder (); a.accept (aBuilder); authorizedRepresentative (aBuilder.build ()); } return thisAsT (); } @Nonnull public final IMPLTYPE authorizedRepresentative (@Nullable final CorePersonType a) { return authorizedRepresentative (a == null ? null : PersonPojo.builder (a)); } @Nonnull public final IMPLTYPE authorizedRepresentative (@Nullable final PersonPojo.Builder a) { return authorizedRepresentative (a == null ? null : a.build ()); } @Nonnull public final IMPLTYPE authorizedRepresentative (@Nullable final PersonPojo a) { m_aAuthorizedRepresentative = a; return thisAsT (); } @OverridingMethodsMustInvokeSuper public void checkConsistency () { if (m_eQueryDefinition == null) throw new IllegalStateException ("Query Definition must be present"); if (StringHelper.hasNoText (m_sRequestID)) throw new IllegalStateException ("ID must be present"); if (m_eResponseOption == null) throw new IllegalStateException ("Response Option must be present"); if (StringHelper.hasNoText (m_sSpecificationIdentifier)) throw new IllegalStateException ("SpecificationIdentifier must be present"); if (m_aIssueDateTime == null) throw new IllegalStateException ("Issue Date Time must be present"); if (m_aDataConsumer == null) throw new IllegalStateException ("Cata Consumer must be present"); if (m_aDataSubjectLegalPerson == null && m_aDataSubjectNaturalPerson == null) { // No DS is present if (!m_eQueryDefinition.isDataSujectOptional ()) throw new IllegalStateException ("Data Subject must be present"); } else { // More than one DS is present? if (m_aDataSubjectLegalPerson != null && m_aDataSubjectNaturalPerson != null) throw new IllegalStateException ("Data Subject MUST be either legal person OR natural person"); } } @Nonnull public abstract EDMRequest build (); } /** * A builder for a "Concept request".Request a concept response. * * @author Philip Helger */ public static class BuilderConcept extends AbstractBuilder { private final ICommonsList m_aConcepts = new CommonsArrayList <> (); protected BuilderConcept () { super (EToopQueryDefinitionType.CONCEPT); } @Nonnull public BuilderConcept addConcept (@Nullable final Consumer a) { if (a != null) { final ConceptPojo.Builder aBuilder = ConceptPojo.builder (); a.accept (aBuilder); addConcept (aBuilder.build ()); } return this; } @Nonnull public BuilderConcept addConcept (@Nullable final CCCEVConceptType a) { return addConcept (a == null ? null : ConceptPojo.builder (a)); } @Nonnull public BuilderConcept addConcept (@Nullable final ConceptPojo.Builder a) { return addConcept (a == null ? null : a.build ()); } @Nonnull public BuilderConcept addConcept (@Nullable final ConceptPojo a) { if (a != null) m_aConcepts.add (a); return this; } @Nonnull public BuilderConcept concept (@Nullable final Consumer a) { if (a != null) { final ConceptPojo.Builder aBuilder = ConceptPojo.builder (); a.accept (aBuilder); concept (aBuilder.build ()); } return this; } @Nonnull public BuilderConcept concept (@Nullable final CCCEVConceptType a) { return concept (a == null ? null : ConceptPojo.builder (a)); } @Nonnull public BuilderConcept concept (@Nullable final ConceptPojo.Builder a) { return concept (a == null ? null : a.build ()); } @Nonnull public BuilderConcept concept (@Nullable final ConceptPojo a) { if (a != null) m_aConcepts.set (a); else m_aConcepts.clear (); return this; } @Nonnull public BuilderConcept concepts (@Nullable final ConceptPojo... a) { m_aConcepts.setAll (a); return this; } @Nonnull public BuilderConcept concepts (@Nullable final Iterable a) { m_aConcepts.setAll (a); return this; } @Nonnull public BuilderConcept concepts (@Nullable final Iterable a, @Nonnull final Function aMapper) { m_aConcepts.setAllMapped (a, aMapper); return thisAsT (); } @Override public void checkConsistency () { super.checkConsistency (); if (m_aConcepts.isEmpty ()) throw new IllegalStateException ("A Query Definition of type 'Concept' must contain a Concept"); } @Override @Nonnull public EDMRequest build () { checkConsistency (); return new EDMRequest (m_eQueryDefinition, m_sRequestID, m_eResponseOption, m_sSpecificationIdentifier, m_aIssueDateTime, m_aProcedure, m_aFullfillingRequirements, m_aDataConsumer, m_sConsentToken, m_sDatasetIdentifier, m_aDataSubjectLegalPerson, m_aDataSubjectNaturalPerson, m_aAuthorizedRepresentative, new EDMRequestPayloadConcepts (m_aConcepts)); } } /** * Builder for a "Documents by distribution request". Request 1-n documents - * either directly or as a reference. * * @author Philip Helger */ public static class BuilderDocumentsByDistribution extends AbstractBuilder { private final ICommonsList m_aDistributions = new CommonsArrayList <> (); protected BuilderDocumentsByDistribution () { super (EToopQueryDefinitionType.DOCUMENT_BY_DISTRIBUTION); } @Nonnull public final BuilderDocumentsByDistribution addDistribution (@Nullable final Consumer a) { if (a != null) { final DistributionPojo.Builder aBuilder = DistributionPojo.builder (); a.accept (aBuilder); addDistribution (aBuilder.build ()); } return this; } @Nonnull public BuilderDocumentsByDistribution addDistribution (@Nullable final DCatAPDistributionType a) { return addDistribution (a == null ? null : DistributionPojo.builder (a)); } @Nonnull public BuilderDocumentsByDistribution addDistribution (@Nullable final DistributionPojo.Builder a) { return addDistribution (a == null ? null : a.build ()); } @Nonnull public BuilderDocumentsByDistribution addDistribution (@Nullable final DistributionPojo a) { if (a != null) m_aDistributions.add (a); return this; } @Nonnull public final BuilderDocumentsByDistribution distribution (@Nullable final Consumer a) { if (a != null) { final DistributionPojo.Builder aBuilder = DistributionPojo.builder (); a.accept (aBuilder); distribution (aBuilder.build ()); } return this; } @Nonnull public BuilderDocumentsByDistribution distribution (@Nullable final DCatAPDistributionType a) { return distribution (a == null ? null : DistributionPojo.builder (a)); } @Nonnull public BuilderDocumentsByDistribution distribution (@Nullable final DistributionPojo.Builder a) { return distribution (a == null ? null : a.build ()); } @Nonnull public BuilderDocumentsByDistribution distribution (@Nullable final DistributionPojo a) { if (a != null) m_aDistributions.set (a); else m_aDistributions.clear (); return this; } @Nonnull public BuilderDocumentsByDistribution distributions (@Nullable final DistributionPojo... a) { m_aDistributions.setAll (a); return this; } @Nonnull public BuilderDocumentsByDistribution distributions (@Nullable final Iterable a) { m_aDistributions.setAll (a); return this; } @Nonnull public BuilderDocumentsByDistribution distributions (@Nullable final Iterable a, @Nonnull final Function aMapper) { m_aDistributions.setAllMapped (a, aMapper); return thisAsT (); } @Override public void checkConsistency () { super.checkConsistency (); if (m_aDistributions.isEmpty ()) throw new IllegalStateException ("A Query Definition of type 'Document' must contain a Distribution"); } @Override @Nonnull public EDMRequest build () { checkConsistency (); return new EDMRequest (m_eQueryDefinition, m_sRequestID, m_eResponseOption, m_sSpecificationIdentifier, m_aIssueDateTime, m_aProcedure, m_aFullfillingRequirements, m_aDataConsumer, m_sConsentToken, m_sDatasetIdentifier, m_aDataSubjectLegalPerson, m_aDataSubjectNaturalPerson, m_aAuthorizedRepresentative, new EDMRequestPayloadDistribution (m_aDistributions)); } } /** * Builder for a "Document by ID request". Request 1 document directly. * * @author Philip Helger */ public static class BuilderDocumentByID extends AbstractBuilder { private String m_sDocumentID; protected BuilderDocumentByID () { super (EToopQueryDefinitionType.DOCUMENT_BY_ID); } @Nonnull public BuilderDocumentByID documentID (@Nullable final String s) { m_sDocumentID = s; return this; } @Override public void checkConsistency () { super.checkConsistency (); if (m_sDocumentID == null) throw new IllegalStateException ("A Query Definition of type 'GetObjectByID' must contain a Document ID"); } @Override @Nonnull public EDMRequest build () { checkConsistency (); return new EDMRequest (m_eQueryDefinition, m_sRequestID, m_eResponseOption, m_sSpecificationIdentifier, m_aIssueDateTime, m_aProcedure, m_aFullfillingRequirements, m_aDataConsumer, m_sConsentToken, m_sDatasetIdentifier, m_aDataSubjectLegalPerson, m_aDataSubjectNaturalPerson, m_aAuthorizedRepresentative, new EDMRequestPayloadDocumentID (m_sDocumentID)); } } private static void _applySlots (@Nonnull final SlotType aSlot, @Nonnull final EDMRequest.AbstractBuilder aBuilder) { final String sName = aSlot.getName (); final ValueType aSlotValue = aSlot.getSlotValue (); switch (sName) { case SlotSpecificationIdentifier.NAME: if (aSlotValue instanceof StringValueType) { final String sValue = ((StringValueType) aSlotValue).getValue (); aBuilder.specificationIdentifier (sValue); } break; case SlotIssueDateTime.NAME: if (aSlotValue instanceof DateTimeValueType) { final LocalDateTime aCal = ((DateTimeValueType) aSlotValue).getValue (); aBuilder.issueDateTime (aCal); } break; case SlotProcedure.NAME: if (aSlotValue instanceof InternationalStringValueType) { final InternationalStringType aIntString = ((InternationalStringValueType) aSlotValue).getValue (); aBuilder.procedure (aIntString); } break; case SlotFullfillingRequirements.NAME: if (aSlotValue instanceof CollectionValueType) { final List aElements = ((CollectionValueType) aSlotValue).getElement (); for (final ValueType aElement : aElements) if (aElement instanceof AnyValueType) { final Object aElementValue = ((AnyValueType) aElement).getAny (); if (aElementValue instanceof Node) aBuilder.addFullfillingRequirement (new RequirementMarshaller ().read ((Node) aElementValue)); } } break; case SlotConsentToken.NAME: if (aSlotValue instanceof StringValueType) { final String sValue = ((StringValueType) aSlotValue).getValue (); aBuilder.consentToken (sValue); } break; case SlotDatasetIdentifier.NAME: if (aSlotValue instanceof StringValueType) { final String sValue = ((StringValueType) aSlotValue).getValue (); aBuilder.datasetIdentifier (sValue); } break; case SlotDataConsumer.NAME: if (aSlotValue instanceof AnyValueType) { final Node aAny = (Node) ((AnyValueType) aSlotValue).getAny (); aBuilder.dataConsumer (AgentPojo.builder (new AgentMarshaller ().read (aAny))); } break; case SlotDataSubjectLegalPerson.NAME: if (aSlotValue instanceof AnyValueType) { final Node aAny = (Node) ((AnyValueType) aSlotValue).getAny (); aBuilder.dataSubject (BusinessPojo.builder (new BusinessMarshaller ().read (aAny))); } break; case SlotDataSubjectNaturalPerson.NAME: if (aSlotValue instanceof AnyValueType) { final Node aAny = (Node) ((AnyValueType) aSlotValue).getAny (); aBuilder.dataSubject (PersonPojo.builder (new PersonMarshaller ().read (aAny))); } break; case SlotAuthorizedRepresentative.NAME: if (aSlotValue instanceof AnyValueType) { final Node aAny = (Node) ((AnyValueType) aSlotValue).getAny (); aBuilder.authorizedRepresentative (PersonPojo.builder (new PersonMarshaller ().read (aAny))); } break; case SlotConceptRequestList.NAME: if (aSlotValue instanceof CollectionValueType) { final List aElements = ((CollectionValueType) aSlotValue).getElement (); if (!aElements.isEmpty ()) { for (final ValueType aElement : aElements) if (aElement instanceof AnyValueType) { final Object aElementValue = ((AnyValueType) aElement).getAny (); if (aElementValue instanceof Node) ((EDMRequest.BuilderConcept) aBuilder).addConcept (new ConceptMarshaller ().read ((Node) aElementValue)); } } } break; case SlotDistributionRequestList.NAME: if (aSlotValue instanceof CollectionValueType) { final List aElements = ((CollectionValueType) aSlotValue).getElement (); if (!aElements.isEmpty ()) { for (final ValueType aElement : aElements) if (aElement instanceof AnyValueType) { final Object aElementValue = ((AnyValueType) aElement).getAny (); if (aElementValue instanceof Node) ((EDMRequest.BuilderDocumentsByDistribution) aBuilder).addDistribution (new DistributionMarshaller ().read ((Node) aElementValue)); } } } break; case SlotId.NAME: if (aSlotValue instanceof StringValueType) { final String sValue = ((StringValueType) aSlotValue).getValue (); ((EDMRequest.BuilderDocumentByID) aBuilder).documentID (sValue); } break; default: throw new IllegalStateException ("Found unsupported slot '" + sName + "'"); } } @Nonnull public static EDMRequest create (@Nonnull final QueryRequest aQueryRequest) { ValueEnforcer.notNull (aQueryRequest, "QueryRequest"); final QueryType aQuery = aQueryRequest.getQuery (); ValueEnforcer.notNull (aQuery, "QueryRequest.Query"); final ICommonsSet aQuerySlotNames = new CommonsHashSet <> (aQuery.getSlot (), SlotType::getName); // Enforce a default response option final EDMRequest.AbstractBuilder aBuilder; if (aQuerySlotNames.contains (SlotConceptRequestList.NAME)) aBuilder = builderConcept (); else if (aQuerySlotNames.contains (SlotDistributionRequestList.NAME)) aBuilder = builderDocumentsByDistribution (); else if (aQuerySlotNames.contains (SlotId.NAME)) aBuilder = builderDocumentByID (); else throw new IllegalStateException ("Cannot read this QueryRequest as a TOOP EDM request"); // Request ID aBuilder.id (aQueryRequest.getId ()); // Top level slots for (final SlotType aSlot : aQueryRequest.getSlot ()) _applySlots (aSlot, aBuilder); // Query slots for (final SlotType aSlot : aQuery.getSlot ()) if (aSlot != null) _applySlots (aSlot, aBuilder); // Default response option is "CONTAINED" for backwards compatibility from // beta3 to beta2 EToopResponseOptionType eResponseOption = null; final ResponseOptionType aResponseOption = aQueryRequest.getResponseOption (); if (aResponseOption != null && aResponseOption.getReturnType () != null) { eResponseOption = EToopResponseOptionType.getFromIDOrNull (aResponseOption.getReturnType ()); } aBuilder.responseOption (eResponseOption != null ? eResponseOption : EToopResponseOptionType.INLINE); return aBuilder.build (); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy