001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.openid.connect.sdk.federation.policy.operations;
019
020
021import java.util.LinkedHashSet;
022import java.util.LinkedList;
023import java.util.Set;
024
025import com.nimbusds.openid.connect.sdk.federation.policy.language.OperationName;
026import com.nimbusds.openid.connect.sdk.federation.policy.language.PolicyOperation;
027import com.nimbusds.openid.connect.sdk.federation.policy.language.PolicyViolationException;
028import com.nimbusds.openid.connect.sdk.federation.policy.language.StringOperation;
029
030
031/**
032 * One-of (one_of) operation.
033 *
034 * <p>Example policy:
035 *
036 * <pre>
037 * "request_object_signing_alg" : { "one_of" : [ "ES256", "ES384", "ES512" ] }
038 * </pre>
039 *
040 * <p>Input:
041 *
042 * <pre>
043 * "request_object_signing_alg" : "ES384"
044 * </pre>
045 *
046 * <p>Result:
047 *
048 * <pre>
049 * "request_object_signing_alg" : "ES384"
050 * </pre>
051 *
052 * <p>Related specifications:
053 *
054 * <ul>
055 *     <li>OpenID Connect Federation 1.0, section 4.1.2.
056 * </ul>
057 */
058public class OneOfOperation extends AbstractSetBasedOperation implements StringOperation {
059        
060        
061        public static final OperationName NAME = new OperationName("one_of");
062        
063        
064        @Override
065        public OperationName getOperationName() {
066                return NAME;
067        }
068        
069        
070        @Override
071        public PolicyOperation merge(final PolicyOperation other) throws PolicyViolationException {
072                
073                OneOfOperation otherTyped = Utils.castForMerge(other, OneOfOperation.class);
074                
075                // intersect
076                Set<String> combinedConfig = new LinkedHashSet<>(setConfig);
077                combinedConfig.retainAll(otherTyped.getStringListConfiguration());
078                
079                OneOfOperation mergedPolicy = new OneOfOperation();
080                mergedPolicy.configure(new LinkedList<>(combinedConfig));
081                return mergedPolicy;
082        }
083        
084        
085        @Override
086        public String apply(final String value)
087                throws PolicyViolationException {
088                
089                if (setConfig == null) {
090                        throw new IllegalStateException("The policy is not initialized");
091                }
092                
093                if (value == null) {
094                        throw new PolicyViolationException("Value not set");
095                }
096                
097                if (! setConfig.contains(value)) {
098                        throw new PolicyViolationException("Value " + value + " not in policy list: " + setConfig);
099                }
100                
101                return value;
102        }
103}