TypesTable.cpp

Go to the documentation of this file.
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 /*
00021  * This class stores the list of parsed types 
00022  */
00023  
00024 #include "schemaparser/TypesTable.h"
00025 
00026 using namespace std;
00027 namespace Schema {
00028 
00029 TypesTable::TypesTable()
00030 {
00031   currentId = Schema::XSD_ANYURI + 1;
00032   numTypes = 0;
00033   typesArray = new XSDType *[nSize = 10];
00034 
00035   //map of simple types
00036   basicTypes["string"] = Schema::XSD_STRING;
00037   basicTypes["integer"] = Schema::XSD_INTEGER;
00038   basicTypes["int"] = Schema::XSD_INT;
00039   basicTypes["byte"] = Schema::XSD_BYTE;
00040   basicTypes["positiveInteger"] = Schema::XSD_POSINT;
00041   basicTypes["unsignedInt"] = Schema::XSD_UINT;
00042   basicTypes["long"] = Schema::XSD_LONG;
00043   basicTypes["unsignedLong"] = Schema::XSD_ULONG;
00044   basicTypes["short"] = Schema::XSD_SHORT;
00045   basicTypes["unsignedShort"] = Schema::XSD_USHORT;
00046   basicTypes["decimal"] = Schema::XSD_DECIMAL;
00047   basicTypes["float"] = Schema::XSD_FLOAT;
00048   basicTypes["double"] = Schema::XSD_DOUBLE;
00049   basicTypes["boolean"] = Schema::XSD_BOOLEAN;
00050   basicTypes["time"] = Schema::XSD_TIME;
00051   basicTypes["dateTime"] = Schema::XSD_DATETIME;
00052   basicTypes["date"] = Schema::XSD_DATE;
00053   basicTypes["token"] = Schema::XSD_TOKEN;
00054   basicTypes["QName"] = Schema::XSD_QNAME;
00055   basicTypes["NCName"] = Schema::XSD_NCNAME;
00056   basicTypes["NMTOKEN"] = Schema::XSD_NMTOKEN;
00057   basicTypes["NMTOKENS"] = Schema::XSD_NMTOKENS;
00058   basicTypes["base64Binary"] = Schema::XSD_BASE64BIN;
00059   basicTypes["hexBinary"] = Schema::XSD_HEXBIN;
00060   basicTypes["anyType"] = Schema::XSD_ANYTYPE;
00061   basicTypes["any"] = Schema::XSD_ANY;
00062   basicTypes["anyURI"] = Schema::XSD_ANYURI;
00063 }
00064 
00065 
00066 TypesTable::~TypesTable()
00067 {
00068   clean();
00069 }
00070 
00071 
00072 std::string
00073 TypesTable::getAtomicTypeName(Schema::Type t)const
00074 {
00075   
00076   for(
00077       std::map<std::string,int>::const_iterator it =
00078         basicTypes.begin();
00079       it != basicTypes.end();
00080       it++){
00081 
00082     if (it->second == t)
00083       return it->first;
00084   }
00085   return "";
00086 }
00087 
00088 void
00089 TypesTable::clean()
00090 {
00091   for (map < string, int >::iterator it = Id.begin(); it != Id.end();
00092        ++it)
00093     delete getTypePtr(it->second);
00094   numTypes = 0;
00095   if (typesArray)
00096     {
00097       delete[] typesArray;
00098       typesArray = 0;
00099     }
00100 }
00101 
00102 
00103 int TypesTable::addType(XSDType * type)
00104 {
00105   Qname qn = type->getQname();
00106   string type_name(qn.getLocalName());
00107   int i = 0;
00108 
00109   //  string ns(qn.getNamespace());
00110   if (type_name.empty())
00111     {
00112 
00113       //create an anonymous type name
00114       ostringstream tmp_name_str;
00115       tmp_name_str << "type" << numTypes;
00116       type_name = tmp_name_str.str();
00117       type->setName(type_name);
00118       type->setAnonymous(true);                 //auto generated name
00119     }
00120   ensureCapacity();
00121 
00122   //  std::cout<<type_name<<" ";
00123 
00124   //add the typename and its id  to the map
00125   if ((i = Id[type_name]) != 0)
00126     {
00127 
00128       //this type was refernced earlier.
00129       typesArray[i - (Schema::XSD_ANYURI + 1)] = type;
00130       type->setTypeId(i);
00131       //  cout<<i<<endl;
00132       return i;
00133     }
00134 
00135   else
00136     {
00137       Id[type_name] = currentId;
00138       type->setTypeId(currentId);
00139       typesArray[numTypes] = type;
00140       currentId++;
00141       numTypes++;
00142       //      cout<<type->getName()<<" "<<currentId -1<<"  "<<numTypes<<" "<<this<<endl;
00143       return currentId - 1;
00144     }
00145 }
00146 
00147 
00148 
00149 
00150 //get the type id of a type
00151 int TypesTable::getTypeId(const Qname & name, bool create)
00152 {
00153   int typeId;
00154   if (name.getNamespace() == Schema::SchemaUri)
00155     {
00156 
00157       //This is one of the basic types
00158       typeId = basicTypes[name.getLocalName()];
00159       if(typeId==0) //if this is a basic type which is not mapped,treat as string
00160         typeId=Schema::XSD_STRING;
00161     }
00162 
00163   else if (name.getNamespace() == m_tnsUri )
00164     typeId = Id[name.getLocalName()];
00165   else if (name.getNamespace().empty()){
00166 
00167     typeId = basicTypes[name.getLocalName()];
00168     if(typeId==0) 
00169       typeId = Id[name.getLocalName()];
00170     if(typeId==0) 
00171       typeId = Schema::XSD_INVALID;
00172   }
00173   else
00174     return Schema::XSD_INVALID;                                 //the Type does not belong to this schema
00175   if (typeId == 0 && create)
00176     {
00177 
00178       //handle forward reference
00179       //create an id and return its value
00180       Id[name.getLocalName()] = currentId;
00181       ensureCapacity();
00182       typesArray[numTypes] = 0;
00183       currentId++;
00184       numTypes++;
00185       typeId = currentId - 1;
00186       //std::cout<<typeId<<" "<<name<<endl;
00187 
00188     }
00189   return typeId;
00190 }
00191 
00192 //for types present in an imported schema we cant use the type id
00193 //since its specific to the imported schema
00194 //we need to keep a local type id 
00195 int 
00196 TypesTable::addExternalTypeId(const Qname & type, const XSDType * pType)
00197 {
00198   for (unsigned int i = 0; i < extRefs_.size(); i++)
00199     if (extRefs_[i].qname == type)
00200       return extRefs_[i].localTypeId;
00201   
00202   extRefs er;
00203   er.qname = (pType)?pType->getQname():type;
00204   er.localTypeId = currentId;
00205   extRefs_.push_back(er);
00206   ensureCapacity();
00207   typesArray[numTypes] = const_cast<XSDType*>(pType);
00208   numTypes++;
00209   return currentId++;
00210 
00211 }
00212 
00213 //adds a type into a type table for a given type id
00214 //used for types present in imported schemas but referenced in current schema
00215 int TypesTable::addExtType(XSDType * type, int localId)
00216 {
00217   int index = localId - Schema::XSD_ANYURI - 1;
00218   if (index >= numTypes)
00219     return 0;
00220   typesArray[index] = type;
00221   return localId;
00222 }
00223 
00224 //increase the array storage if necessary
00225 void TypesTable::ensureCapacity()
00226 {
00227   if (numTypes >= nSize)
00228     {
00229       XSDType **tempArray = new XSDType *[numTypes + 5];
00230       for (int ind = 0; ind < nSize; ind++)
00231         tempArray[ind] = typesArray[ind];
00232       delete[] typesArray;
00233       typesArray = tempArray;
00234       nSize = numTypes + 5;
00235     }
00236 }
00237 
00238 
00239 #if 0
00240 
00241 /*
00242   Takes a XSD type  and an accessor name to determine if the
00243   accessor is a descendant of the given type
00244   If found ,returns the schematype Id of the found element
00245   and populates an array of indices denoting the path
00246   from the parent to accessor .
00247   otherwise return 0(invalid type)
00248 
00249 */
00250 int TypesTable::getCompleteXpath(int elemId, string & childName,
00251                                  int *xPath, int limits, int &offset)
00252 {
00253     int childId = 0, type = 0, i = 0, childIndex;
00254     bool found = false;
00255     if (xPath == 0 || limits == 0)
00256         return 0;
00257     XSDType *pType = getTypePtr(elemId);
00258     if (pType == 0)
00259         return 0;
00260     if (pType->isSimple())
00261         return 0;
00262     ComplexType *ct = (ComplexType *) pType;
00263     for (i = 0; i < ct->getNumChildren(); i++)
00264         if (ct->getChildName(i) == childName)
00265     {
00266         childId = ct->getChildType(i);
00267         childIndex = i;
00268     }
00269     if (childId == 0)
00270     {
00271 
00272 /*
00273  childName is not a child of elemId,
00274  so call this method recursively
00275 */
00276         for (int i = 0; i < ct->getNumChildren() && !childId; i++)
00277         {
00278             if (childId =
00279                 getCompleteXpath(ct->getChildType(i), childName, xPath + 1,
00280                 limits - 1, ++offset))
00281                 xPath[0] = i;
00282 
00283             else
00284                 offset--;
00285         }
00286     }
00287 
00288     else
00289     {
00290         xPath[0] = childIndex;
00291         offset++;
00292     }
00293     return childId;
00294 }
00295 #endif
00296 
00297 
00298 bool 
00299 TypesTable::detectUndefinedTypes(void)
00300 {
00301     for (int i = 0; i < numTypes; i++)
00302         if (typesArray[i] == 0)
00303             return true;
00304     return false;
00305 }
00306 
00307 
00308 void 
00309 TypesTable::resolveForwardElementRefs(const string & name, Element & e)
00310 {
00311     for (int i = 0; i < numTypes; i++)
00312         if (typesArray[i] != 0)
00313     {
00314         if (!typesArray[i]->isSimple())
00315         {
00316             ComplexType *ct = (ComplexType *) typesArray[i];
00317             ct->matchElementRef(name, e);
00318         }
00319     }
00320 }
00321 
00322 
00323 void
00324 TypesTable::resolveForwardAttributeRefs(const string & name, Attribute & a)
00325 {
00326     for (int i = 0; i < numTypes; i++)
00327         if (typesArray[i] != 0)
00328     {
00329         if (!typesArray[i]->isSimple())
00330         {
00331             ComplexType *ct = (ComplexType *) typesArray[i];
00332             ct->matchAttributeRef(name, a);
00333         }
00334     }
00335 }
00336 
00337 
00338 void 
00339 TypesTable::printUndefinedTypes(ostream & out)
00340 {
00341     for (map < string, int >::iterator it = Id.begin(); it != Id.end();
00342         ++it)
00343     {
00344         if (getTypePtr(it->second) == 0)
00345           out << "Could not find {"<<m_tnsUri << "}:" << it->first << std::endl;
00346     }
00347 }
00348 
00349 XSDType *
00350 TypesTable::getTypePtr(int id) const
00351 {
00352   
00353   // this is a basic XSD type
00354   if (id < Schema::XSD_ANYURI + 1 || id > Schema::XSD_ANYURI + numTypes) {
00355  
00356     //    if (id > Schema::XSD_ANYURI + numTypes) 
00357       //      std::cout<<id<<" "<<this<<"  "<<numTypes<<std::endl;
00358     return 0;
00359   }
00360   return typesArray[id - (Schema::XSD_ANYURI + 1)];
00361 }
00362 
00363 }
00364 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by  doxygen 1.6.2