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.*;
022
023import com.nimbusds.oauth2.sdk.ParseException;
024import com.nimbusds.oauth2.sdk.util.JSONUtils;
025import com.nimbusds.openid.connect.sdk.federation.policy.language.*;
026
027
028/**
029 * Add (add) operation.
030 *
031 * <p>Example policy:
032 *
033 * <pre>
034 * "contacts" : { "add" : "[email protected]" }
035 * </pre>
036 *
037 * <p>Input:
038 *
039 * <pre>
040 * "contacts" : "[email protected]"
041 * </pre>
042 *
043 * <p>Result:
044 *
045 * <pre>
046 * "contacts" : [ "[email protected]", "[email protected]" ]
047 * </pre>
048 *
049 * <p>Related specifications:
050 *
051 * <ul>
052 *     <li>OpenID Connect Federation 1.0, section 4.1.4.
053 * </ul>
054 */
055public class AddOperation extends AbstractSetBasedOperation implements StringConfiguration, StringListOperation {
056        
057        
058        public static final OperationName NAME = new OperationName("add");
059        
060        
061        @Override
062        public OperationName getOperationName() {
063                return NAME;
064        }
065        
066        
067        @Override
068        public void configure(final String parameter) {
069                configType = ConfigurationType.STRING;
070                configure(Collections.singletonList(parameter));
071        }
072        
073        
074        @Override
075        public void parseConfiguration(final Object jsonEntity) throws ParseException {
076                
077                if (jsonEntity instanceof String) {
078                        configure(JSONUtils.toString(jsonEntity));
079                } else {
080                        // String list
081                        super.parseConfiguration(jsonEntity);
082                }
083        }
084        
085        
086        @Override
087        public Map.Entry<String,Object> toJSONObjectEntry() {
088                if (configType == null) {
089                        throw new IllegalStateException("The policy is not initialized");
090                }
091                Object value;
092                if (configType.equals(ConfigurationType.STRING_LIST)) {
093                        if (getStringListConfiguration().size() > 1) {
094                                value = getStringListConfiguration();
095                        } else {
096                                value = getStringListConfiguration().get(0);
097                        }
098                } else if (configType.equals(ConfigurationType.STRING)) {
099                        value = getStringConfiguration();
100                } else {
101                        throw new IllegalStateException("Unsupported configuration type: " + configType);
102                }
103                return new AbstractMap.SimpleImmutableEntry<>(getOperationName().getValue(), value);
104        }
105        
106        
107        @Override
108        public String getStringConfiguration() {
109                return getStringListConfiguration().get(0);
110        }
111        
112        
113        @Override
114        public PolicyOperation merge(final PolicyOperation other)
115                throws PolicyViolationException {
116                
117                AddOperation otherTyped = Utils.castForMerge(other, AddOperation.class);
118                
119                List<String> combined = new LinkedList<>();
120                combined.addAll(getStringListConfiguration());
121                combined.addAll(otherTyped.getStringListConfiguration());
122                
123                AddOperation mergedPolicy = new AddOperation();
124                mergedPolicy.configure(combined);
125                return mergedPolicy;
126        }
127        
128        
129        @Override
130        public List<String> apply(final List<String> value) {
131                
132                if (setConfig == null) {
133                        throw new IllegalStateException("The policy is not initialized");
134                }
135                
136                if (value == null) {
137                        return Collections.unmodifiableList(new LinkedList<>(setConfig));
138                }
139                
140                List<String> result = new LinkedList<>(value);
141                result.addAll(setConfig);
142                return result;
143        }
144}