001/*-
002 * #%L
003 * HAPI FHIR - Server Framework
004 * %%
005 * Copyright (C) 2014 - 2024 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.rest.server.interceptor.consent;
021
022import org.apache.commons.lang3.Validate;
023import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
024import org.hl7.fhir.instance.model.api.IBaseResource;
025
026import java.util.stream.Stream;
027
028public class ConsentOutcome implements IConsentVote {
029
030        /**
031         * Convenience constant containing <code>new ConsentOutcome(ConsentOperationStatusEnum.PROCEED)</code>
032         */
033        public static final ConsentOutcome PROCEED = new ConsentOutcome(ConsentOperationStatusEnum.PROCEED);
034        /**
035         * Convenience constant containing <code>new ConsentOutcome(ConsentOperationStatusEnum.REJECT)</code>
036         */
037        public static final ConsentOutcome REJECT = new ConsentOutcome(ConsentOperationStatusEnum.REJECT);
038        /**
039         * Convenience constant containing <code>new ConsentOutcome(ConsentOperationStatusEnum.AUTHORIZED)</code>
040         */
041        public static final ConsentOutcome AUTHORIZED = new ConsentOutcome(ConsentOperationStatusEnum.AUTHORIZED);
042
043        private final ConsentOperationStatusEnum myStatus;
044        private final IBaseOperationOutcome myOperationOutcome;
045        private final IBaseResource myResource;
046
047        public ConsentOutcome(ConsentOperationStatusEnum theStatus) {
048                this(theStatus, null, null);
049        }
050
051        public ConsentOutcome(ConsentOperationStatusEnum theStatus, IBaseOperationOutcome theOperationOutcome) {
052                this(theStatus, theOperationOutcome, null);
053        }
054
055        public ConsentOutcome(ConsentOperationStatusEnum theStatus, IBaseResource theResource) {
056                this(theStatus, null, theResource);
057        }
058
059        private ConsentOutcome(
060                        ConsentOperationStatusEnum theStatus,
061                        IBaseOperationOutcome theOperationOutcome,
062                        IBaseResource theResource) {
063                Validate.notNull(theStatus, "theStatus must not be null");
064                Validate.isTrue(
065                                !(theOperationOutcome != null && theResource != null),
066                                "theOperationOutcome and theResource must not both be null");
067                myStatus = theStatus;
068                myOperationOutcome = theOperationOutcome;
069                myResource = theResource;
070        }
071
072        /**
073         * Evaluate all verdicts together, allowing any to veto (i.e. REJECT) the operation.
074         * <ul>
075         * <li>If any vote is REJECT, then the result is a REJECT vote.
076         * <li>If no vote is REJECT, and any vote is AUTHORIZED, then the result is one of the AUTHORIZED votes.
077         * <li>If no vote is REJECT or AUTHORIZED, the result is a PROCEED vote.
078         * </ul>
079         *
080         * @return REJECT if any reject, AUTHORIZED if no REJECT and some AUTHORIZED, PROCEED if empty or all PROCEED
081         */
082        public static ConsentOutcome parallelReduce(Stream<ConsentOutcome> theOutcomes) {
083                return IConsentVote.parallelReduce(ConsentOutcome.PROCEED, theOutcomes);
084        }
085
086        /**
087         * Evaluate verdicts in order, taking the first "decision" (i.e. first non-PROCEED) verdict.
088         *
089         * @return the first decisive verdict, or theSeed when empty or all PROCEED.
090         */
091        public static ConsentOutcome serialReduce(Stream<ConsentOutcome> theStream) {
092                return IConsentVote.serialReduce(ConsentOutcome.PROCEED, theStream);
093        }
094
095        public ConsentOperationStatusEnum getStatus() {
096                return myStatus;
097        }
098
099        public IBaseOperationOutcome getOperationOutcome() {
100                return myOperationOutcome;
101        }
102
103        public IBaseResource getResource() {
104                return myResource;
105        }
106}