4023b52b6194b2463ccb4fc95954ef847e1904aa
[shibboleth/cpp-xmltooling.git] / xmltooling / util / TemplateEngine.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 xmltooling/util/TemplateEngine.h
19  * 
20  * Simple template replacement engine.
21  */
22
23 #ifndef __xmltooling_template_h__
24 #define __xmltooling_template_h__
25
26 #include <xmltooling/io/GenericRequest.h>
27
28 #include <map>
29 #include <string>
30 #include <iostream>
31 #include <vector>
32
33 #if defined (_MSC_VER)
34     #pragma warning( push )
35     #pragma warning( disable : 4251 )
36 #endif
37
38 namespace xmltooling {
39
40     /**
41      * Simple template replacement engine. Supports the following:
42      * <ul>
43      *  <li> &lt;mlp key/&gt; </li>
44      *  <li> &lt;mlpif key&gt; stuff &lt;/mlpif&gt;</li>
45      *  <li> &lt;mlpifnot key&gt; stuff &lt;/mlpifnot&gt;</li>
46      *  <li> &lt;mlpfor key&gt; stuff &lt;/mlpfor&gt;</li>
47      * </ul>
48      * 
49      * The default tag prefix is "mlp". This can be overridden for
50      * compatibility.
51      */
52     class XMLTOOL_API TemplateEngine
53     {
54         MAKE_NONCOPYABLE(TemplateEngine);
55     public:
56         TemplateEngine() {
57             setTagPrefix("mlp"); 
58         }
59
60         virtual ~TemplateEngine() {}
61         
62         /**
63          * Sets the tag name to use when locating template replacement tags.
64          * 
65          * @param tagPrefix base prefix for tags
66          */
67         void setTagPrefix(const char* tagPrefix);
68         
69         /**
70          * Interface to parameters to plug into templates.
71          * Allows callers to supply a more dynamic lookup mechanism to supplement a basic map.
72          */
73         class XMLTOOL_API TemplateParameters {
74             // MAKE_NONCOPYABLE(TemplateParameters);
75         public:
76             TemplateParameters() : m_request(NULL) {}
77             virtual ~TemplateParameters() {}
78             
79             /** Map of known parameters to supply to template. */
80             std::map<std::string,std::string> m_map;
81             std::map<std::string,std::vector<TemplateParameters> > m_collectionMap;
82             
83             /** Request from client that resulted in template being processed. */
84             const GenericRequest* m_request;
85             
86             /**
87              * Returns the value of a parameter to plug into the template.
88              * 
89              * @param name  name of parameter
90              * @return value of parameter, or NULL
91              */
92             virtual const char* getParameter(const char* name) const {
93                 std::map<std::string,std::string>::const_iterator i=m_map.find(name);
94                 return (i!=m_map.end() ? i->second.c_str() : (m_request ? m_request->getParameter(name) : NULL));
95             }
96
97             /**
98              * Returns the collection of parameters to plug into the template.
99              * 
100              * @param name  name of parameter collection
101              * @return vector of parameters
102              */
103             virtual const std::vector<TemplateParameters>& getParameterCollection(const char* name) const {
104                 std::map<std::string,std::vector<TemplateParameters> >::const_iterator i=m_collectionMap.find(name);
105                 return (i->second);
106             }
107         };
108         
109         /**
110          * Processes template from an input stream and executes replacements and
111          * conditional logic based on parameters. 
112          * 
113          * @param is            input stream providing template
114          * @param os            output stream to send results of executing template
115          * @param parameters    parameters to plug into template
116          * @param e             optional exception to extract parameters from
117          */
118         virtual void run(
119             std::istream& is,
120             std::ostream& os,
121             const TemplateParameters& parameters,
122             const XMLToolingException* e=NULL
123             ) const;
124
125         /**
126          * List of non-built-in characters considered "unsafe" and requiring HTML encoding.
127          * The default set is #%&():[]\\`{}
128          */
129         static std::string unsafe_chars;
130
131     private:
132         void trimspace(std::string& s) const;
133         void html_encode(std::ostream& os, const char* start) const;
134         void process(
135             bool visible,
136             const std::string& buf,
137             const char*& lastpos,
138             std::ostream& os,
139             const TemplateParameters& parameters,
140             const XMLToolingException* e
141             ) const;
142             
143         std::string keytag,iftag,ifendtag,ifnottag,ifnotendtag,fortag,forendtag;
144     };
145 };
146
147 #if defined (_MSC_VER)
148     #pragma warning( pop )
149 #endif
150
151 #endif /* __xmltooling_template_h__ */