src/tools/schema.cpp

00001 /* 
00002  * wsdlpull - A C++ parser  for WSDL  (Web services description language)
00003  * Copyright (C) 2005-2007 Vivek Krishna
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library 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 GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public
00016  * License along with this library; if not, write to the Free
00017  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  */
00019 
00020 //This file parses a sample schema document and validates/generates an instance
00021   
00022 #include <iostream>
00023 #include <fstream>
00024 #include <string>
00025 #include "xmlpull/XmlPullParser.h"
00026 #include "xmlpull/XmlPullParserException.h"
00027 #include "schemaparser/SchemaParser.h"
00028 #include "schemaparser/SchemaValidator.h"
00029 #include "schemaparser/TypeContainer.h"
00030 #include "schemaparser/SchemaParserException.h"
00031 using namespace std;
00032 using namespace Schema;
00033 
00034 void
00035 usage(void)
00036 {
00037   cout << "Usage: schema [options] <schema_file_name> [-i schema instance file name]"<<endl;
00038   cout << "Example:schema po.xsd -i po.xsi"<<endl;
00039   cout << "Example:schema first-building-blocks.xsd -i first.xml "<<endl;
00040   std::cout<<"Options"<<std::endl;
00041   std::cout<<"   -x host[:port] Use HTTP proxy on given port"<<std::endl;
00042   std::cout<<"   -U user[:password] Specify Proxy authentication"<<std::endl;
00043   std::cout<<"   -g generate an xml instance for a top level element in the schema"<<std::endl;
00044   std::cout<<"   -v Verbose mode"<<std::endl;
00045   cout << endl;
00046 }
00047 
00048 int 
00049 main (int argc, char *argv[]) 
00050 {
00051   ifstream schfs;
00052   ifstream insfs;
00053   SchemaParser * sp=0;
00054   bool brkloop =false;
00055   bool accept_password =false;
00056   unsigned char  lvl = 0;
00057   bool genInstance = false;
00058   int i =1;
00059   for (;i<argc && !brkloop;){
00060     switch(argv[i][0]){
00061     case '-'://option
00062       {
00063         std::string opt(argv[i]+1);
00064         if (opt=="v"){
00065           lvl = 2;
00066           i++;
00067         }
00068         else if (opt == "g"){
00069 
00070           genInstance = true;
00071           i++;
00072         }
00073         else if (opt == "x"){
00074           opt = argv[i+1];
00075           size_t pos=opt.find(':');
00076           XmlUtils::setProxyHost (opt);
00077           if(pos==std::string::npos){
00078             
00079             XmlUtils::setProxyHost (XmlUtils::getProxyHost () + ":80");
00080           }
00081           XmlUtils::setProxy (true);
00082           i+=2;
00083         }
00084         else if (opt == "U"){
00085           opt = argv[i+1];
00086           size_t pos=opt.find(':');
00087           XmlUtils::setProxyUser (opt.substr(0,pos));
00088           if(pos!=std::string::npos)
00089             XmlUtils::setProxyPass (opt.substr(pos+1));
00090           else
00091             accept_password = true;
00092           i+=2;
00093           XmlUtils::setProxy (true);
00094         }
00095         else if (opt =="h"){
00096           usage();
00097           exit(0);
00098         }
00099         else{
00100           std::cerr<<"Unknown option "<<argv[i]<<std::endl;
00101           usage();
00102           exit(2);
00103         }
00104         break;
00105       }
00106     default:
00107       brkloop = true;
00108       //end of options
00109       break;
00110     }
00111   }
00112 
00113   if (XmlUtils::getProxy () && accept_password){
00114      
00115     XmlUtils::setProxyPass (XmlUtils::acceptSecretKey("Proxy Password"));
00116     std::cout<<endl;
00117   }
00118 
00119   if (i < argc){
00120 
00121     sp = new SchemaParser (argv[i]);
00122     i++;
00123   }
00124   else
00125     {
00126       usage();
00127       return 2;
00128     }
00129   
00130   try{
00131 
00132     if (!sp)
00133       return 1;
00134     sp->setWarningLevel(lvl);
00135     if (sp->parseSchemaTag ())
00136       {
00137         if (lvl >=2)
00138           cout << "Successfully parsed schema  " <<sp->getNamespace() << endl;
00139         //sp->print (cout);
00140       }
00141     else {
00142 
00143       std::cerr<<"Could not successfully parse "<<argv[i-1]<<std::endl;
00144       std::cerr<<"Run the command with -v option for more details"<<std::endl;
00145       return 1;
00146     }
00147   
00148     if (genInstance ) {
00149 
00150       std::string elemName;
00151 
00152       Schema::Element element;
00153       const Schema::SchemaParser::ElementList & el = sp->getElements(); 
00154       //the global element for which to generate the instance
00155       if (i <=argc && argv[i]){
00156         bool found = false;
00157         elemName = std::string(argv[i]);
00158                   
00159         for ( Schema::SchemaParser::ElementList::const_iterator eli= el.begin();
00160               eli!=el.end() && !found;
00161               eli++)
00162           {
00163             if (eli->getName()  == elemName){ 
00164               found = true;
00165               element = *eli;
00166               
00167               
00168             }
00169           }
00170         if (!found) {
00171                           
00172           std::cerr<<"element '"<<elemName<<"' not found in the schema.Try 'schema -g "<<argv[2]<<"'  to see the list of elements in the schema"<<std::endl;
00173           return 1;       
00174         }
00175       }
00176       else {
00177         int n = 0;
00178         for ( Schema::SchemaParser::ElementList::const_iterator eli= el.begin();
00179               eli!=el.end();
00180               eli++,n++)
00181           {
00182             if (n !=0)
00183               std::cout<<n<<"."<<eli->getName()<<std::endl;
00184           }
00185         std::cout<<"Which element should I generate an instance for [1.."<<n-1<<"]?";
00186         std::cin>>n;
00187 
00188         n++; // locate the element in the list (first element bydefault is <schema> so skip it
00189         for ( Schema::SchemaParser::ElementList::const_iterator eli= el.begin();
00190               eli!=el.end() && n ;
00191               eli++,n--) element = *eli;
00192       } 
00193   
00194       SchemaValidator * sv = new SchemaValidator(sp);
00195       return sv->instance(element.getName(),(Schema::Type)element.getType());    
00196     }
00197     else if (i <argc )
00198       {
00199         std::string xmlDoc;
00200         XmlUtils::fetchUri(argv[i+1],xmlDoc);
00201         insfs.open (xmlDoc.c_str());    //open the schema instance file
00202         if (insfs.fail ())
00203           {
00204             cerr << "An Error occrred while opening " << argv[i+1] << endl;
00205             return 1;
00206           }
00207         i++;
00208         XmlPullParser * xpp = new XmlPullParser (insfs);
00209         xpp->setFeature (FEATURE_PROCESS_NAMESPACES, true);
00210         xpp->require (XmlPullParser::START_DOCUMENT, "", "");
00211         SchemaValidator * sv= new SchemaValidator(sp);
00212         while (xpp->getEventType () != xpp->END_DOCUMENT)
00213           {
00214             xpp->nextTag ();
00215             if (xpp->getEventType () == xpp->END_DOCUMENT)
00216               break;
00217             Qname elemName (xpp->getName ());
00218             elemName.setNamespace(xpp->getNamespace());
00219             const Element * e = sp->getElement (elemName);
00220             if(e){
00221               int typeId = e->getType () ;
00222               //for each element in the instance doc we call the
00223               //validator with the parser instance of the instance file
00224               // and the element's type identifier
00225               TypeContainer * t = sv->validate (xpp, typeId);
00226 
00227               cout << "{"<<elemName.getNamespace () << "}" << elemName. 
00228                 getLocalName ()<<std::endl;
00229               //once validated the element instance is stored
00230               //in the type container from which values can be
00231               //obtained or just printed
00232               t->print(cout);
00233               std::cout<<std::endl;
00234             }else{
00235               std::cerr<<"Unkown element "<<elemName.getLocalName()<<std::endl;
00236             }
00237           }
00238       }
00239     delete sp;
00240     return 0;
00241   }
00242   catch (SchemaParserException spe)
00243     {
00244       cerr<<"An Exception occurred ...@"<<spe.line
00245           <<":"<<spe.col<<endl;
00246 
00247       cerr<<spe.description<<endl;
00248     }
00249   catch (XmlPullParserException xpe)
00250     {
00251       cerr<<"An Exception occurred ...@"<<xpe.line
00252           <<":"<<xpe.col<<endl;
00253 
00254       cerr<<xpe.description<<endl;
00255     }
00256   return 1;
00257 }

Generated on Fri Oct 19 19:34:04 2007 for wsdlpull by  doxygen 1.4.6