• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

soa.h

Go to the documentation of this file.
00001 /* Copyright (c) 2008-2009, AbiSource Corporation B.V.
00002  * All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *     * Redistributions of source code must retain the above copyright
00007  *       notice, this list of conditions and the following disclaimer.
00008  *     * Redistributions in binary form must reproduce the above copyright
00009  *       notice, this list of conditions and the following disclaimer in the
00010  *       documentation and/or other materials provided with the distribution.
00011  *     * Neither the name of AbiSource Corporation B.V. nor the
00012  *       names of other contributors may be used to endorse or promote products
00013  *       derived from this software without specific prior written permission.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY ABISOURCE CORPORATION B.V. AND OTHER
00016  * CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
00017  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00018  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ABISOURCE
00019  * CORPORATION B.V OR OTHER CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00020  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00021  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00022  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00023  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00024  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00025  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  */
00027 
00028 
00029 #ifndef __SOA__
00030 #define __SOA__
00031 
00032 #ifdef _MSC_VER
00033 #include "msc_stdint.h"
00034 #else
00035 #include <stdint.h>
00036 #endif
00037 #include <boost/lexical_cast.hpp>
00038 #include <boost/shared_ptr.hpp>
00039 #include <string>
00040 #include <vector>
00041 #include "soa_types.h"
00042 #include "soa_result.h"
00043 
00044 namespace soa {
00045 
00046 class function_arg {
00047 public:
00048     function_arg(const std::string& n, Type t)
00049         : name_(n),
00050         type_(t)
00051     {}
00052 
00053     virtual ~function_arg() {}
00054 
00055     const std::string& name() const {
00056         return name_;
00057     }
00058 
00059     Type type() const {
00060         return type_;
00061     }
00062 
00063     virtual bool type_props() const {
00064         return false;
00065     }
00066 
00067     virtual std::string props() const {
00068         return "";
00069     }
00070 
00071     // FIXME: returning an std::string is inefficient for large blocks of
00072     // data; we should make it a boost::shared_ptr<std::string>
00073     virtual std::string str() const = 0;
00074 
00075 private:
00076     std::string name_;
00077     Type type_;
00078 };
00079 
00080 class function_arg_string : public function_arg {
00081 public:
00082     function_arg_string(const std::string& n, const std::string& value)
00083         : function_arg(n, STRING_TYPE),
00084         value_(value)
00085     {}
00086 
00087     virtual std::string str() const {
00088         return value_;
00089     }
00090 
00091 private:
00092     std::string value_;
00093 };
00094 
00095 class function_arg_int : public function_arg {
00096 public:
00097     function_arg_int(const std::string& n, int64_t value)
00098         : function_arg(n, INT_TYPE),
00099         value_(value)
00100     {}
00101 
00102     virtual std::string str() const {
00103         try {
00104             return boost::lexical_cast<std::string>(value_);
00105         } catch (boost::bad_lexical_cast &) {
00106             return "0";
00107         }
00108     }
00109 
00110 private:
00111     int64_t value_;
00112 };
00113 
00114 class function_arg_bool : public function_arg {
00115 public:
00116     function_arg_bool(const std::string& n, bool value)
00117         : function_arg(n, BOOL_TYPE),
00118         value_(value)
00119     {}
00120 
00121     virtual std::string str() const {
00122         return value_ ? "true" : "false";
00123     }
00124 
00125 private:
00126     bool value_;
00127 };
00128 
00129 class function_arg_base64bin : public function_arg {
00130 public:
00131     function_arg_base64bin(Base64Bin value)
00132         : function_arg(value.name(), BASE64BIN_TYPE),
00133         value_(value)
00134     {}
00135 
00136     virtual std::string str() const {
00137         return value_.value();
00138     }
00139 
00140 private:
00141     Base64Bin value_;
00142 };
00143 
00144 class function_arg_array : public function_arg {
00145 public:
00146     // TODO: automatically deduce the type of the array
00147     function_arg_array(const std::string& n, ArrayPtr value, Type element_type)
00148         : function_arg(n, ARRAY_TYPE),
00149         value_(value),
00150         element_type_(element_type)
00151     {}
00152 
00153     virtual bool type_props() const {
00154         return true;
00155     }
00156 
00157     virtual std::string props() const {
00158         if (value_)
00159             return "SOAP-ENC:arrayType=\"" + soap_type(element_type_) + "[" + boost::lexical_cast<std::string>(value_->size()) + "]\"" + " " + "SOAP-ENC:offset=\"[0]\"";
00160         return "SOAP-ENC:arrayType=\"xsd:anyType[0]\" xsi:nil=\"true\"";
00161     }
00162 
00163     virtual std::string str() const {
00164         std::string ret = "\n";
00165         if (!value_)
00166             return ret;
00167 
00168         for (size_t i = 0; i < value_->size(); i++)
00169         {
00170             GenericPtr val = value_->operator[](i);
00171             if (!val)
00172                 continue;
00173 
00174             // TODO: generalize this; for now, we only support arrays of integers
00175             IntPtr val_int = boost::dynamic_pointer_cast<soa::Int>(val);
00176             if (!val_int)
00177                 continue;
00178             function_arg_int arg(val->name(), val_int->value());
00179 
00180             ret += "<" + arg.name() + " " + "xsi:type=\"" + soap_type(arg.type()) + "\"" + ">" + arg.str() + "</" + arg.name() + ">\n";
00181         }
00182         return ret;
00183     }
00184 
00185 private:
00186     ArrayPtr value_;
00187     Type element_type_;
00188 };
00189 
00190 class function_call {
00191 public:
00192     function_call() {}
00193 
00194     function_call(const std::string& req, const std::string& resp)
00195         : request_(req),
00196         response_(resp)
00197     {}
00198 
00199     function_call& operator()(std::string name, const char* value) {
00200         args.push_back(boost::shared_ptr<function_arg>(new function_arg_string(name, value)));
00201         return *this;
00202     }
00203 
00204     function_call& operator()(std::string name, std::string value) {
00205         args.push_back(boost::shared_ptr<function_arg>(new function_arg_string(name, value)));
00206         return *this;
00207     }
00208 
00209     function_call& operator()(std::string name, int64_t value) {
00210         args.push_back(boost::shared_ptr<function_arg>(new function_arg_int(name, value)));
00211         return *this;
00212     }
00213 
00214     function_call& operator()(std::string name, bool value) {
00215         args.push_back(boost::shared_ptr<function_arg>(new function_arg_bool(name, value)));
00216         return *this;
00217     }
00218 
00219     function_call& operator()(Base64Bin value) {
00220         args.push_back(boost::shared_ptr<function_arg>(new function_arg_base64bin(value)));
00221         return *this;
00222     }
00223 
00224     function_call& operator()(std::string name, ArrayPtr value, Type type) {
00225         args.push_back(boost::shared_ptr<function_arg>(new function_arg_array(name, value, type)));
00226         return *this;
00227     }
00228 
00229     const std::string& request() const {
00230         return request_;
00231     }
00232 
00233     const std::string& response() const {
00234         return response_;
00235     }
00236 
00237     void add_arg(boost::shared_ptr<function_arg> arg) {
00238         args.push_back(arg);
00239     }
00240 
00241     std::string str() const {
00242         std::string ret;
00243         // TODO: XML escape args/values
00244         for (std::vector< boost::shared_ptr<function_arg> >::const_iterator cit = args.begin(); cit != args.end(); cit++) {
00245             const function_arg& arg = **cit;
00246             ret += "<" + arg.name() + " " + "xsi:type=\"" + soap_type(arg.type()) + "\"" +
00247                         (arg.type_props() ? " " + arg.props() : "") +
00248                 ">" +
00249                 arg.str() +
00250                 "</" + arg.name() + ">\n";
00251         }
00252         return ret;
00253     }
00254 
00255 private:
00256     std::string request_;
00257     std::string response_;
00258     std::vector< boost::shared_ptr<function_arg> > args;
00259 };
00260 typedef boost::shared_ptr<soa::function_call> function_call_ptr;
00261 
00262 class header {
00263 public:
00264     std::string str() const {
00265         return "";
00266     }
00267 };
00268 
00269 class body {
00270 public:
00271     body(const std::string& ns_ref_)
00272         : ns_ref(ns_ref_)
00273     {}
00274 
00275     body(const std::string& ns_ref_, const function_call& fc)
00276         : ns_ref(ns_ref_),
00277         fc_(fc)
00278     {}
00279 
00280     const function_call& function() const {
00281         return fc_;
00282     }
00283 
00284     void set_function(function_call fc) {
00285         fc_ = fc;
00286     }
00287 
00288     std::string str() const {
00289         return "<SOAP-ENV:Body>\n" \
00290             "<" + ns_ref + ":" + fc_.request() + ">\n" +
00291             fc_.str() +
00292             "</" + ns_ref + ":" + fc_.request() + ">\n" \
00293             "</SOAP-ENV:Body>\n";
00294     }
00295 
00296 private:
00297     std::string ns_ref;
00298     function_call fc_;
00299 };
00300 
00301 class method_invocation {
00302 public:
00303     method_invocation(const std::string& custom_ns)
00304         : custom_ns_(custom_ns),
00305         custom_ns_ref_("nsref"),
00306         body_(custom_ns_ref_)
00307     {}
00308 
00309     method_invocation(const std::string& custom_ns, function_call fc)
00310         : custom_ns_(custom_ns),
00311         custom_ns_ref_("nsref"),
00312         body_(custom_ns_ref_, fc)
00313     {}
00314 
00315     const function_call& function() const {
00316         return body_.function();
00317     }
00318 
00319     std::string str() const {
00320         return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
00321             "<SOAP-ENV:Envelope " +
00322             default_namespaces() +
00323             " xmlns:" + custom_ns_ref_ + "=\"" + custom_ns_ + "\"" +
00324             " " + encoding_style() + ">\n" +
00325             header_.str() +
00326             body_.str() +
00327             "</SOAP-ENV:Envelope>";
00328     }
00329 
00330 private:
00331     std::string default_namespaces() const {
00332         return "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"" \
00333             " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" \
00334             " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" \
00335             " xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\"";
00336     }
00337 
00338     std::string encoding_style() const {
00339         return "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"";
00340     }
00341 
00342     std::string input_name_;
00343     std::string output_name_;
00344     std::string custom_ns_;
00345     std::string custom_ns_ref_;
00346     header header_;
00347     body body_;
00348 };
00349 }
00350 
00351 #endif /* __SOA__ */

Generated on Sun Feb 14 2021 for AbiWord by  doxygen 1.7.1