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.ArrayList;
21  import java.util.Collection;
22  import java.util.Set;
23  
24  import org.opensaml.xml.util.DatatypeHelper;
25  import org.opensaml.xml.util.LazySet;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  import edu.internet2.middleware.shibboleth.common.attribute.BaseAttribute;
30  import edu.internet2.middleware.shibboleth.common.attribute.provider.BasicAttribute;
31  import edu.internet2.middleware.shibboleth.common.attribute.resolver.AttributeResolutionException;
32  import edu.internet2.middleware.shibboleth.common.attribute.resolver.provider.ShibbolethResolutionContext;
33  
34  /**
35   * The RegexAttributeDefinition allows regular expression based replacements on attribute values, using the regex syntax
36   * allowed by {@link java.util.regex.Pattern}.
37   */
38  public class MappedAttributeDefinition extends BaseAttributeDefinition {
39  
40      /** Class logger. */
41      private static Logger log = LoggerFactory.getLogger(MappedAttributeDefinition.class);
42  
43      /** Default return value. */
44      private String defaultValue;
45  
46      /** Whether the definition passes thru unmatched values. */
47      private boolean passThru;
48  
49      /** Value maps. */
50      private Collection<ValueMap> valueMaps;
51  
52      /** Constructor. */
53      public MappedAttributeDefinition() {
54          valueMaps = new ArrayList<ValueMap>(5);
55      }
56  
57      /** {@inheritDoc} */
58      protected BaseAttribute doResolve(ShibbolethResolutionContext resolutionContext)
59              throws AttributeResolutionException {
60          BasicAttribute<String> attribute = new BasicAttribute<String>();
61          attribute.setId(getId());
62  
63          Collection<?> values = getValuesFromAllDependencies(resolutionContext);
64          if (values == null || values.isEmpty()) {
65              log.debug("Attribute Definition {}: No values from dependency attribute attribute {}", getId(),
66                      getDependencyIds());
67              if (!DatatypeHelper.isEmpty(getDefaultValue())) {
68                  log.debug(
69                          "Attribute Definition {}: Default value is not empty, adding it as the value for this attribute",
70                          getId());
71                  attribute.getValues().add(getDefaultValue());
72              }
73              return attribute;
74          }
75  
76          Set<String> mappedValues;
77          for (Object o : values) {
78              if (o == null) {
79                  log.debug("Attribute Definition {}: null attribute value, skipping it", getId());
80                  continue;
81              }
82              mappedValues = mapValue(o.toString());
83              attribute.getValues().addAll(mappedValues);
84          }
85  
86          return attribute;
87      }
88  
89      /**
90       * Maps the value from a dependency in to the value(s) for this attribute.
91       * 
92       * @param value the value from the dependency
93       * 
94       * @return the set of attribute values that the given dependency value maps in to
95       */
96      protected Set<String> mapValue(String value) {
97          log.debug("Attribute Definition {}: mapping depdenency attribute value {}", getId(), value);
98          
99          LazySet<String> mappedValues = new LazySet<String>();
100 
101         boolean valueMapMatch = false;
102         if (!DatatypeHelper.isEmpty(value)) {
103             for (ValueMap valueMap : valueMaps) {
104                 mappedValues.addAll(valueMap.evaluate(value));
105                 if (!mappedValues.isEmpty()) {
106                     valueMapMatch = true;
107                 }
108             }
109 
110             if (!valueMapMatch) {
111                 if (passThru) {
112                     mappedValues.add(value);
113                 } else if (getDefaultValue() != null) {
114                     mappedValues.add(getDefaultValue());
115                 }
116             }
117         }
118 
119         log.debug("Attribute Definition {}: mapped depdenency attribute value {} to the values {}", new Object[] {
120                 getId(), value, mappedValues, });
121         
122         return mappedValues;
123     }
124 
125     /** {@inheritDoc} */
126     public void validate() throws AttributeResolutionException {
127         if (passThru && !DatatypeHelper.isEmpty(defaultValue)) {
128             log.error("MappedAttributeDefinition (" + getId()
129                     + ") may not have a DefaultValue string with passThru enabled.");
130             throw new AttributeResolutionException("MappedAttributeDefinition (" + getId()
131                     + ") may not have a DefaultValue string with passThru enabled.");
132         }
133     }
134 
135     /**
136      * Gets the default return value.
137      * 
138      * @return the default return value.
139      */
140     public String getDefaultValue() {
141         return defaultValue;
142     }
143 
144     /**
145      * Sets the default return value.
146      * 
147      * @param newDefaultValue the default return value
148      */
149     public void setDefaultValue(String newDefaultValue) {
150         defaultValue = newDefaultValue;
151     }
152 
153     /**
154      * Gets whether the definition passes thru unmatched values.
155      * 
156      * @return whether the definition passes thru unmatched values.
157      */
158     public boolean isPassThru() {
159         return passThru;
160     }
161 
162     /**
163      * Sets whether the definition passes thru unmatched values.
164      * 
165      * @param newPassThru whether the definition passes thru unmatched values.
166      */
167     public void setPassThru(boolean newPassThru) {
168         passThru = newPassThru;
169     }
170 
171     /**
172      * Get the value maps.
173      * 
174      * @return the value maps.
175      */
176     public Collection<ValueMap> getValueMaps() {
177         return valueMaps;
178     }
179 
180 }