Attribute lookup, port ACL code and mainline SP code to Session/Attribute API.
[shibboleth/cpp-sp.git] / shibsp / attribute / Attribute.h
1 /*
2  *  Copyright 2001-2007 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 that understand them, however. 
52      */
53     class SHIBSP_API Attribute
54     {
55         MAKE_NONCOPYABLE(Attribute);
56     protected:
57         /**
58          * Constructor
59          * 
60          * @param id    Attribute identifier 
61          */
62         Attribute(const char* id) : m_id(id ? id : "") {
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             const char* id = in.first().name();
76             if (id && *id)
77                 m_id = id;
78             else
79                 throw AttributeException("No id found in marshalled attribute content.");
80         }
81         
82
83         /**
84          * Maintains a copy of serialized attribute values, when possible.
85          * 
86          * <p>Implementations should maintain the array when values are added or removed.
87          */
88         mutable std::vector<std::string> m_serialized;
89
90     public:
91         virtual ~Attribute() {}
92         
93         /**
94          * Returns the Attribute identifier.
95          * 
96          * @return Attribute identifier
97          */
98         const char* getId() const {
99             return m_id.c_str();
100         }
101
102         /**
103          * Indicates whether case sensitivity should apply to basic value comparisons.
104          *
105          * @return  true iff value comparisons should be case sensitive
106          */
107         virtual bool isCaseSensitive() const {
108             return true;
109         }
110         
111         /**
112          * Returns the number of values.
113          * 
114          * @return  number of values
115          */
116         virtual size_t valueCount() const {
117             return m_serialized.size();
118         }
119         
120         /**
121          * Returns serialized Attribute values encoded as UTF-8 strings.
122          * 
123          * @return  an immutable vector of values
124          */
125         virtual const std::vector<std::string>& getSerializedValues() const {
126             return m_serialized;
127         }
128         
129         /**
130          * Informs the Attribute that values have changed and any serializations
131          * must be cleared. 
132          */
133         virtual void clearSerializedValues()=0;
134         
135         /**
136          * Marshalls an Attribute for remoting.
137          * 
138          * <p>This allows Attribute objects to be communicated across process boundaries
139          * without excess XML parsing. The DDF returned must be a struct containing
140          * a single list member named with the Attribute's "id". The name of the struct
141          * should contain the registered name of the Attribute implementation.
142          */
143         virtual DDF marshall() const {
144             DDF ddf(NULL);
145             ddf.structure().addmember(m_id.c_str()).list();
146             return ddf;
147         }
148         
149         /**
150          * Unmarshalls a remoted Attribute.
151          * 
152          * @param in    remoted Attribute data
153          * @return  a resolved Attribute of the proper subclass 
154          */
155         static Attribute* unmarshall(DDF& in);
156         
157         /** A function that unmarshalls remoted data into the proper Attribute subclass. */
158         typedef Attribute* AttributeFactory(DDF& in);
159
160         /**
161          * Registers an AttributeFactory function for a given attribute "type".
162          * 
163          * @param type      string used at the root of remoted Attribute structures
164          * @param factory   factory function
165          */        
166         static void registerFactory(const char* type, AttributeFactory* factory) {
167             m_factoryMap[type] = factory;
168         }
169
170         /**
171          * Deregisters an AttributeFactory function for a given attribute "type".
172          * 
173          * @param type      string used at the root of remoted Attribute structures
174          */        
175         static void deregisterFactory(const char* type) {
176             m_factoryMap.erase(type);
177         }
178
179         /**
180          * Clears the map of factories.
181          */
182         static void deregisterFactories() {
183             m_factoryMap.clear();
184         }
185         
186     private:
187         static std::map<std::string,AttributeFactory*> m_factoryMap;
188         std::string m_id;
189     };
190
191 #if defined (_MSC_VER)
192     #pragma warning( pop )
193 #endif
194
195     /** Registers built-in Attribute types into the runtime. */
196     void registerAttributeFactories();
197     
198 };
199
200 #endif /* __shibsp_attribute_h__ */