View Javadoc

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