wsdlpull 1.23
|
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