Imported Upstream version 2.2.1+dfsg
[shibboleth/sp.git] / shibsp / attribute / Attribute.h
1 /*
2  *  Copyright 2001-2009 Internet2
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 /**
18  * @file shibsp/attribute/Attribute.h
19  *
20  * A resolved attribute.
21  */
22
23 #ifndef __shibsp_attribute_h__
24 #define __shibsp_attribute_h__
25
26 #include <shibsp/exceptions.h>
27 #include <shibsp/remoting/ddf.h>
28
29 #include <map>
30 #include <string>
31 #include <vector>
32
33 namespace shibsp {
34
35 #if defined (_MSC_VER)
36     #pragma warning( push )
37     #pragma warning( disable : 4251 )
38 #endif
39
40     /**
41      * A resolved attribute.
42      *
43      * <p>Resolved attributes are a neutral construct that represent both simple and
44      * complex attribute data structures that might be found in SAML assertions
45      * or obtained from other sources.
46      *
47      * <p>Attributes consist of an id/name that is locally unique (that is, unique to a
48      * configuration at any given point in time) and zero or more values. Values can
49      * be of any type or structure, but will generally be made available to applications
50      * only if a serialized string form exists. More complex values can be used with
51      * access control plugins and other components that understand them, however.
52      */
53     class SHIBSP_API Attribute
54     {
55         MAKE_NONCOPYABLE(Attribute);
56     protected:
57         /**
58          * Constructor
59          *
60          * @param ids   array with primary identifier in first position, followed by any aliases
61          */
62         Attribute(const std::vector<std::string>& ids) : m_id(ids), m_caseSensitive(true), m_internal(false) {
63         }
64
65         /**
66          * Constructs based on a remoted Attribute.
67          *
68          * <p>This allows Attribute objects to be recreated after marshalling.
69          * The DDF supplied must be a struct containing a single list member named
70          * with the Attribute's "id" and containing the values.
71          *
72          * @param in    input object containing marshalled Attribute
73          */
74         Attribute(DDF& in);
75
76         /**
77          * Maintains a copy of serialized attribute values, when possible.
78          *
79          * <p>Implementations should maintain the array when values are added or removed.
80          */
81         mutable std::vector<std::string> m_serialized;
82
83     public:
84         virtual ~Attribute() {}
85
86         /**
87          * Returns the Attribute identifier.
88          *
89          * @return the Attribute identifier
90          */
91         const char* getId() const {
92             return m_id.front().c_str();
93         }
94
95         /**
96          * Returns all of the effective names for the Attribute.
97          *
98          * @return immutable array of identifiers, with the primary ID in the first position
99          */
100         const std::vector<std::string>& getAliases() const {
101             return m_id;
102         }
103
104         /**
105          * Returns all of the effective names for the Attribute.
106          *
107          * @return mutable array of identifiers, with the primary ID in the first position
108          */
109         std::vector<std::string>& getAliases() {
110             return m_id;
111         }
112
113         /**
114          * Sets whether case sensitivity should apply to basic value comparisons.
115          *
116          * @param caseSensitive  true iff value comparisons should be case sensitive
117          */
118         void setCaseSensitive(bool caseSensitive) {
119             m_caseSensitive = caseSensitive;
120         }
121
122         /**
123          * Sets whether the attribute should be exported for CGI use.
124          *
125          * @param export  true iff the attribute should <strong>NOT</strong> be exported
126          */
127         void setInternal(bool internal) {
128             m_internal = internal;
129         }
130
131         /**
132          * Indicates whether case sensitivity should apply to basic value comparisons.
133          *
134          * @return  true iff value comparisons should be case sensitive
135          */
136         bool isCaseSensitive() const {
137             return m_caseSensitive;
138         }
139
140         /**
141          * Indicates whether the attribute should be exported for CGI use.
142          *
143          * @return  true iff the attribute should <strong>NOT</strong> be exported
144          */
145         bool isInternal() const {
146             return m_internal;
147         }
148
149         /**
150          * Returns the number of values.
151          *
152          * @return  number of values
153          */
154         virtual size_t valueCount() const {
155             return m_serialized.size();
156         }
157
158         /**
159          * Returns serialized Attribute values encoded as UTF-8 strings.
160          *
161          * @return  an immutable vector of values
162          */
163         virtual const std::vector<std::string>& getSerializedValues() const {
164             return m_serialized;
165         }
166
167         /**
168          * Informs the Attribute that values have changed and any serializations
169          * must be cleared.
170          */
171         virtual void clearSerializedValues()=0;
172
173         /**
174          * Gets the string equivalent of the value at the specified position (starting from zero).
175          *
176          * @param index position of value
177          * @return the specified value in its "string" form, or NULL if undefined
178          */
179         virtual const char* getString(size_t index) const {
180             return m_serialized[index].c_str();
181         }
182
183         /**
184          * Gets the "scope" of the value at the specified position (starting from zero).
185          *
186          * @param index position of value
187          * @return the specified value's "scope", or NULL if attribute is unscoped
188          */
189         virtual const char* getScope(size_t index) const {
190             return NULL;
191         }
192
193         /**
194          * Removes the value at the specified position (starting from zero).
195          *
196          * @param index position of value to remove
197          */
198         virtual void removeValue(size_t index) {
199             if (index < m_serialized.size())
200                 m_serialized.erase(m_serialized.begin() + index);
201         }
202
203         /**
204          * Marshalls an Attribute for remoting.
205          *
206          * <p>This allows Attribute objects to be communicated across process boundaries
207          * without excess XML parsing. The DDF returned must be a struct containing
208          * a single list member named with the Attribute's "id". The name of the struct
209          * should contain the registered name of the Attribute implementation.
210          */
211         virtual DDF marshall() const;
212
213         /**
214          * Unmarshalls a remoted Attribute.
215          *
216          * @param in    remoted Attribute data
217          * @return  a resolved Attribute of the proper subclass
218          */
219         static Attribute* unmarshall(DDF& in);
220
221         /** A function that unmarshalls remoted data into the proper Attribute subclass. */
222         typedef Attribute* AttributeFactory(DDF& in);
223
224         /**
225          * Registers an AttributeFactory function for a given attribute "type".
226          *
227          * @param type      string used at the root of remoted Attribute structures
228          * @param factory   factory function
229          */
230         static void registerFactory(const char* type, AttributeFactory* factory) {
231             m_factoryMap[type] = factory;
232         }
233
234         /**
235          * Deregisters an AttributeFactory function for a given attribute "type".
236          *
237          * @param type      string used at the root of remoted Attribute structures
238          */
239         static void deregisterFactory(const char* type) {
240             m_factoryMap.erase(type);
241         }
242
243         /**
244          * Clears the map of factories.
245          */
246         static void deregisterFactories() {
247             m_factoryMap.clear();
248         }
249
250     private:
251         static std::map<std::string,AttributeFactory*> m_factoryMap;
252         std::vector<std::string> m_id;
253         bool m_caseSensitive,m_internal;
254     };
255
256 #if defined (_MSC_VER)
257     #pragma warning( pop )
258 #endif
259
260     /** Registers built-in Attribute types into the runtime. */
261     void registerAttributeFactories();
262
263 };
264
265 #endif /* __shibsp_attribute_h__ */