1 /*
2 * Copyright [2007] [University Corporation for Advanced Internet Development, Inc.]
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.attributeDefinition;
18
19 import java.util.Collection;
20 import java.util.HashSet;
21 import java.util.Set;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
24 import java.util.regex.PatternSyntaxException;
25
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30 * Performs many to one mapping of source values to a return value. SourceValue strings may include regular expressions
31 * and the ReturnValue may include back references to capturing groups as supported by {@link java.util.regex.Pattern}.
32 */
33 public class ValueMap {
34
35 /** Class logger. */
36 private final Logger log = LoggerFactory.getLogger(ValueMap.class);
37
38 /** Return value. */
39 private String returnValue;
40
41 /** Source values. */
42 private Collection<SourceValue> sourceValues;
43
44 /** Constructor. */
45 public ValueMap() {
46 sourceValues = new HashSet<SourceValue>();
47 }
48
49 /**
50 * Gets the return value.
51 *
52 * @return the return value
53 */
54 public String getReturnValue() {
55 return returnValue;
56 }
57
58 /**
59 * Sets the return value.
60 *
61 * @param newReturnValue the return value
62 */
63 public void setReturnValue(String newReturnValue) {
64 returnValue = newReturnValue;
65 }
66
67 /**
68 * Gets the collection of source values.
69 *
70 * @return the collection of source values
71 */
72 public Collection<SourceValue> getSourceValues() {
73 return sourceValues;
74 }
75
76 /**
77 * Evaluate an incoming attribute value against this value map.
78 *
79 * @param sourceValue incoming attribute value
80 * @return set of new values the incoming value mapped to
81 */
82 public Set<String> evaluate(String sourceValue) {
83 Set<String> mappedValues = new HashSet<String>();
84 Matcher m;
85
86 String newValue;
87 for (SourceValue vmv : sourceValues) {
88 newValue = null;
89 if (vmv.isPartialMatch()) {
90 if (sourceValue.contains(vmv.getValue())) {
91 newValue = returnValue;
92 }
93 } else {
94 try {
95 int flags = vmv.isIgnoreCase() ? Pattern.CASE_INSENSITIVE : 0;
96 m = Pattern.compile(vmv.getValue(), flags).matcher(sourceValue);
97 if (m.matches()) {
98 newValue = m.replaceAll(returnValue);
99 }
100 } catch (PatternSyntaxException e) {
101 log.debug("Error matching value {}. Skipping this value.", sourceValue);
102 }
103 }
104
105 if (newValue != null) {
106 mappedValues.add(returnValue);
107 }
108 }
109
110 return mappedValues;
111 }
112
113 /**
114 * Represents incoming attribute values and rules used for matching them. The value may include regular expressions.
115 */
116 public class SourceValue {
117
118 /**
119 * Value string. This may contain regular expressions.
120 */
121 private String value;
122
123 /**
124 * Whether case should be ignored when matching.
125 */
126 private boolean ignoreCase;
127
128 /**
129 * Whether partial matches should be allowed.
130 */
131 private boolean partialMatch;
132
133 /**
134 * Constructor.
135 *
136 * @param newValue value string
137 * @param newIgnoreCase whether case should be ignored when matching
138 * @param newPartialMatch whether partial matches should be allowed
139 */
140 public SourceValue(String newValue, boolean newIgnoreCase, boolean newPartialMatch) {
141 value = newValue;
142 ignoreCase = newIgnoreCase;
143 partialMatch = newPartialMatch;
144 }
145
146 /**
147 * Gets whether case should be ignored when matching.
148 *
149 * @return whether case should be ignored when matching
150 */
151 public boolean isIgnoreCase() {
152 return ignoreCase;
153 }
154
155 /**
156 * Gets whether partial matches should be allowed.
157 *
158 * @return whether partial matches should be allowed
159 */
160 public boolean isPartialMatch() {
161 return partialMatch;
162 }
163
164 /**
165 * Gets the value string.
166 *
167 * @return the value string.
168 */
169 public String getValue() {
170 return value;
171 }
172
173 /** {@inheritDoc} */
174 public String toString() {
175 return getValue();
176 }
177
178 }
179 }