Move assertions to separate storage records, improve error handling.
[shibboleth/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          * Returns the number of values.
104          * 
105          * @return  number of values
106          */
107         virtual size_t valueCount() const {
108             return m_serialized.size();
109         }
110         
111         /**
112          * Returns serialized Attribute values encoded as UTF-8 strings.
113          * 
114          * @return  an immutable vector of values
115          */
116         virtual const std::vector<std::string>& getSerializedValues() const {
117             return m_serialized;
118         }
119         
120         /**
121          * Informs the Attribute that values have changed and any serializations
122          * must be cleared. 
123          */
124         virtual void clearSerializedValues()=0;
125         
126         /**
127          * Marshalls an Attribute for remoting.
128          * 
129          * <p>This allows Attribute objects to be communicated across process boundaries
130          * without excess XML parsing. The DDF returned must be a struct containing
131          * a single list member named with the Attribute's "id". The name of the struct
132          * should contain the registered name of the Attribute implementation.
133          */
134         virtual DDF marshall() const {
135             DDF ddf(NULL);
136             ddf.structure().addmember(m_id.c_str()).list();
137             return ddf;
138         }
139         
140         /**
141          * Unmarshalls a remoted Attribute.
142          * 
143          * @param in    remoted Attribute data
144          * @return  a resolved Attribute of the proper subclass 
145          */
146         static Attribute* unmarshall(DDF& in);
147         
148         /** A function that unmarshalls remoted data into the proper Attribute subclass. */
149         typedef Attribute* AttributeFactory(DDF& in);
150
151         /**
152          * Registers an AttributeFactory function for a given attribute "type".
153          * 
154          * @param type      string used at the root of remoted Attribute structures
155          * @param factory   factory function
156          */        
157         static void registerFactory(const char* type, AttributeFactory* factory) {
158             m_factoryMap[type] = factory;
159         }
160
161         /**
162          * Deregisters an AttributeFactory function for a given attribute "type".
163          * 
164          * @param type      string used at the root of remoted Attribute structures
165          */        
166         static void deregisterFactory(const char* type) {
167             m_factoryMap.erase(type);
168         }
169
170         /**
171          * Clears the map of factories.
172          */
173         static void deregisterFactories() {
174             m_factoryMap.clear();
175         }
176         
177     private:
178         static std::map<std::string,AttributeFactory*> m_factoryMap;
179         std::string m_id;
180     };
181
182 #if defined (_MSC_VER)
183     #pragma warning( pop )
184 #endif
185
186     /** Registers built-in Attribute types into the runtime. */
187     void registerAttributeFactories();
188     
189 };
190
191 #endif /* __shibsp_attribute_h__ */