CPPSERV


Home Projects Jobs Clientele Contact
CPPSERV Documentation Download TODO Mailing lists Bug tracker News RSS Feed Browse source

IteratorTags.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2009 by Ilya A. Volynets-Evenbakh                  *
00003  *   ilya@total-knowledge.com                                              *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include "StdTagBase.h"
00022 #include <ctype.h>
00023 #include <sstream>
00024 
00025 using namespace servlet::taglib;
00026 using namespace std;
00027 
00028 namespace csp
00029 {
00030 namespace tags
00031 {
00032 
00033 
00044 class AttrIteratorTag: public StdTagBase
00045 {
00046 public:
00047     string m_attribute, m_var, m_type, m_source, m_attrvar;
00048     bool m_required;
00049 public:
00050     AttrIteratorTag(const string& name)
00051         : StdTagBase(name)
00052     {}
00053     virtual void doStartTag(const attribs_t& attribs);
00054     virtual void doEndTag();
00055 };
00056 
00057 void AttrIteratorTag::doStartTag(const Generator::attribs_t& attribs)
00058 {
00059     string constP;
00060     m_required = get_bool_attr(attribs, "required", "csp:foreach_attr");
00061     get_attr(attribs, "attribute", m_attribute, "csp:foreach_attr");
00062     get_attr(attribs, "var", m_var, "csp:foreach_attr");
00063     get_attr(attribs, "type", m_type, "csp:foreach_attr");
00064     get_attr(attribs, "source", m_source, "csp:foreach_attr", "request");
00065     get_attr(attribs, "const", constP, "csp:foreach_attr", "false");
00066     if(constP == "true") // We'll use const_iterator in this case
00067         constP="const_";
00068     else
00069         constP.clear();
00070     if(m_source!="request" && m_source!="session" && m_source!="servlet")
00071         throw runtime_error("csp:foreach_attr: valid values for \"source\": \"request\", \"session\", \"servlet\"");
00072     if(m_source=="servlet")
00073         m_source="this->getServletContext()";
00074     else if(m_source=="session")
00075         m_source="(*request.getSession())";
00076     if(!common_headers_included) {
00077         *header<<"#include <servlet/taglib/MissingAttributeException.h>"<<endl;
00078         // Hmm... should I really do this?
00079         *header<<"using namespace std;"<<endl;
00080         *header<<"using namespace boost;"<<endl;
00081         common_headers_included=true;
00082     }
00083     stringstream s;
00084     m_attrvar = "_csp_attr_"+m_attribute;
00085     transform(m_attrvar.begin(), m_attrvar.end(), m_attrvar.begin(), to_cxx_ident);
00086     s<<"do {\n\t";
00087     s<< "boost::shared_ptr<"<<m_type<<" > "<<m_attrvar<<" =\n\t\t";
00088     s<<     "static_pointer_cast<"<<m_type<<" >("<<m_source<<".getAttribute(\""<<m_attribute<<"\"));\n\t";
00089     s<< "if(!"<<m_attrvar<<") {\n\t\t";
00090     if(m_required) {
00091         s<<"throw MissingAttributeException(\""<<m_attribute<<"\");\n\t";
00092     } else {
00093         stringstream ss;
00094         ss<<"<!-- attribute "<<m_attribute<<" is not set -->\\n";
00095         s<<"out.write(\""<<ss.str()<<"\", "<<ss.str().length()<<");\n\t\t";
00096         s<<"break;\n\t";
00097     }
00098     s<< "}\n\t";
00099     s<< "for("<<m_type<<"::"<<constP<<"iterator "<<m_var<<"=(*"<<m_attrvar<<").begin();";
00100     s<<     m_var<<"!=(*"<<m_attrvar<<").end(); "<<m_var<<"++) {\n\t\t";
00101     *body<<s.str()<<endl;
00102 }
00103 
00104 void AttrIteratorTag::doEndTag()
00105 {
00106     stringstream s;
00107     s<<"\t}\n";
00108     s<<"} while(0);\n";
00109     s<<"/* end csp:foreach_attr: "<<m_attribute<<" */"<<endl;
00110     *body<<s.str();
00111 }
00112 
00113 
00119 
00120 class ListIteratorTag: public StdTagBase
00121 {
00122 public:
00123     string m_list, m_var, m_type;
00124 public:
00125     ListIteratorTag(const string& name)
00126         : StdTagBase(name)
00127     {}
00128     virtual void doStartTag(const attribs_t& attribs);
00129     virtual void doEndTag();
00130 };
00131 
00132 void ListIteratorTag::doStartTag(const Generator::attribs_t& attribs)
00133 {
00134     string constP;
00135     get_attr(attribs, "list", m_list, "csp:foreach_list");
00136     get_attr(attribs, "var", m_var, "csp:foreach_list");
00137     get_attr(attribs, "type", m_type, "csp:foreach_list");
00138     get_attr(attribs, "const", constP, "csp:foreach_list", "false");
00139     if(constP == "true") // We'll use const_iterator in this case
00140         constP="const_";
00141     else
00142         constP.clear();
00143     stringstream s;
00144     s<<"for("<<m_type<<"::"<<constP<<"iterator "<<m_var<<"=("<<m_list<<").begin();";
00145     s<<     m_var<<"!=("<<m_list<<").end(); "<<m_var<<"++) {\n\t";
00146     *body<<s.str()<<endl;
00147 }
00148 
00149 void ListIteratorTag::doEndTag()
00150 {
00151     stringstream s;
00152     s<<"}\n";
00153     s<<"/* end csp:foreach_list: "<<m_list<<" */"<<endl;
00154     *body<<s.str();
00155 }
00156 
00157 }
00158 }
00159 DECLARE_COMPILE_TIME_TAGLIB(csp)
00160 EXPORT_COMPILE_TIME_TAG(csp, foreach_attr, csp::tags::AttrIteratorTag)
00161 EXPORT_COMPILE_TIME_TAG(csp, foreach_list, csp::tags::ListIteratorTag)

SourceForge.net Logo