CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/CondCore/ORA/src/MappingElement.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "MappingElement.h"
00003 //
00004 #include <set>
00005 #include <sstream>
00006 
00007 std::string
00008 ora::MappingElement::classMappingElementType()
00009 {
00010   static std::string s_classMappingElementType = "Class";
00011   return s_classMappingElementType;
00012 }
00013 
00014 std::string
00015 ora::MappingElement::objectMappingElementType()
00016 {
00017   static std::string s_objectMappingElementType = "Object";
00018   return s_objectMappingElementType;
00019 }
00020 
00021 std::string
00022 ora::MappingElement::dependencyMappingElementType()
00023 {
00024   static std::string s_dependencyMappingElementType = "Dependency";
00025   return s_dependencyMappingElementType;
00026 }
00027 
00028 std::string
00029 ora::MappingElement::primitiveMappingElementType()
00030 {
00031   static std::string s_primitiveMappingElementType = "Primitive";
00032   return s_primitiveMappingElementType;
00033 }
00034 
00035 std::string
00036 ora::MappingElement::arrayMappingElementType()
00037 {
00038   static std::string s_arrayMappingElementType = "Array";
00039   return s_arrayMappingElementType;
00040 }
00041 
00042 std::string
00043 ora::MappingElement::CArrayMappingElementType()
00044 {
00045   static std::string s_CArrayMappingElementType = "CArray";
00046   return s_CArrayMappingElementType;
00047 }
00048 
00049 std::string
00050 ora::MappingElement::inlineCArrayMappingElementType()
00051 {
00052   static std::string s_inlineCArrayMappingElementType = "InlineCArray";
00053   return s_inlineCArrayMappingElementType;
00054 }
00055 
00056 std::string
00057 ora::MappingElement::OraReferenceMappingElementType()
00058 {
00059   static std::string s_oraReferenceMappingElementType = "OraReference";
00060   return s_oraReferenceMappingElementType;
00061 }
00062 
00063 std::string
00064 ora::MappingElement::OraPointerMappingElementType()
00065 {
00066   static std::string s_oraPointerMappingElementType = "OraPointer";
00067   return s_oraPointerMappingElementType;
00068 }
00069 
00070 std::string
00071 ora::MappingElement::uniqueReferenceMappingElementType()
00072 {
00073   static std::string s_oraUniqueReferenceMappingElementType = "UniqueReference";
00074   return s_oraUniqueReferenceMappingElementType;
00075 }
00076 
00077 std::string
00078 ora::MappingElement::OraArrayMappingElementType()
00079 {
00080   static std::string s_oraArrayMappingElementType = "OraArray";
00081   return s_oraArrayMappingElementType;
00082 }
00083 
00084 std::string
00085 ora::MappingElement::pointerMappingElementType()
00086 {
00087   static std::string s_pointerMappingElementType = "Pointer";
00088   return s_pointerMappingElementType;
00089 }
00090 
00091 std::string
00092 ora::MappingElement::referenceMappingElementType()
00093 {
00094   static std::string s_referenceMappingElementType = "Reference";
00095   return s_referenceMappingElementType;
00096 }
00097 
00098 std::string
00099 ora::MappingElement::blobMappingElementType()
00100 {
00101   static std::string s_blobMappingElementType = "Blob";
00102   return s_blobMappingElementType;
00103 }
00104 
00105 std::string
00106 ora::MappingElement::namedReferenceMappingElementType()
00107 {
00108   static std::string s_namedReferenceMappingElementType = "NamedReference";
00109   return s_namedReferenceMappingElementType;
00110 }
00111 
00112 bool
00113 ora::MappingElement::isValidMappingElementType( const std::string& elementType )
00114 {
00115   return ( elementType == classMappingElementType() ||
00116            elementType == objectMappingElementType() ||
00117            elementType == dependencyMappingElementType() ||
00118            elementType == primitiveMappingElementType() ||
00119            elementType == arrayMappingElementType() ||
00120            elementType == CArrayMappingElementType() ||
00121            elementType == inlineCArrayMappingElementType() ||
00122            elementType == OraReferenceMappingElementType() ||
00123            elementType == OraPointerMappingElementType() ||
00124            elementType == uniqueReferenceMappingElementType() ||
00125            elementType == OraArrayMappingElementType() ||
00126            elementType == pointerMappingElementType() ||
00127            elementType == referenceMappingElementType() ||
00128            elementType == blobMappingElementType() ||
00129            elementType == namedReferenceMappingElementType() );
00130 }
00131 
00132 std::string
00133 ora::MappingElement::elementTypeAsString( ora::MappingElement::ElementType elementType )
00134 {
00135   switch ( elementType ) {
00136   case Class :
00137     return  classMappingElementType();
00138     break;
00139   case Object :
00140     return  objectMappingElementType();
00141     break;
00142   case Dependency :
00143     return  dependencyMappingElementType();
00144     break;
00145   case Primitive :
00146     return  primitiveMappingElementType();
00147     break;
00148   case Array :
00149     return  arrayMappingElementType();
00150     break;
00151   case CArray :
00152     return  CArrayMappingElementType();
00153     break;
00154   case InlineCArray :
00155     return  inlineCArrayMappingElementType();
00156     break;
00157   case OraReference :
00158     return  OraReferenceMappingElementType();
00159     break;
00160   case OraPointer :
00161     return  OraPointerMappingElementType();
00162     break;
00163   case UniqueReference :
00164     return  uniqueReferenceMappingElementType();
00165     break;
00166   case OraArray :
00167     return  OraArrayMappingElementType();
00168     break;
00169   case Reference :
00170     return  referenceMappingElementType();
00171     break;
00172   case Blob :
00173     return  blobMappingElementType();
00174     break;
00175   case NamedReference :
00176     return  namedReferenceMappingElementType();
00177     break;
00178   case Pointer :
00179     return  pointerMappingElementType();
00180     break;
00181   case Undefined :
00182     // This should never appear
00183     break;
00184   };
00185 
00186   std::stringstream ms;
00187   ms <<"Undefined mapping element type code="<< elementType;
00188   throwException( ms.str(),
00189                   "MappingElement::elementTypeAsString" );
00190   return "";
00191 }
00192 
00193 
00194 ora::MappingElement::ElementType
00195 ora::MappingElement::elementTypeFromString( const std::string& elementType )
00196 {
00197   // Check here the element type
00198   if ( !  isValidMappingElementType( elementType ) ) {
00199     throwException( "\"" + elementType + "\" is not a supported mapping element type",
00200                     "MappingElement::elementTypeFromString" );
00201   }
00202 
00203   ora::MappingElement::ElementType result = Undefined;
00204 
00205   if ( elementType == classMappingElementType() ) {
00206     return Class;
00207   }
00208   if ( elementType == objectMappingElementType() ) {
00209     return Object;
00210   }
00211   if ( elementType == dependencyMappingElementType() ) {
00212     return Dependency;
00213   }
00214   if ( elementType == primitiveMappingElementType() ) {
00215     return Primitive;
00216   }
00217   else if ( elementType == arrayMappingElementType() ) {
00218     return Array;
00219   }
00220   else if ( elementType == CArrayMappingElementType() ) {
00221     return CArray;
00222   }
00223   else if ( elementType == inlineCArrayMappingElementType() ) {
00224     return InlineCArray;
00225   }
00226   else if ( elementType == pointerMappingElementType() ) {
00227     return Pointer;
00228   }
00229   else if ( elementType == referenceMappingElementType() ) {
00230     return Reference;
00231   }
00232   else if ( elementType == OraReferenceMappingElementType() ) {
00233     return OraReference;
00234   }
00235   else if ( elementType == OraPointerMappingElementType() ) {
00236     return OraPointer;
00237   }
00238   else if ( elementType == uniqueReferenceMappingElementType() ) {
00239     return UniqueReference;
00240   }
00241   else if ( elementType == OraArrayMappingElementType() ) {
00242     return OraArray;
00243   }
00244   else if ( elementType == blobMappingElementType() ) {
00245     return Blob;
00246   }
00247   else if ( elementType == namedReferenceMappingElementType() ) {
00248     return NamedReference;
00249   }
00250 
00251   return result;
00252 }
00253 
00254 ora::MappingElement::MappingElement( const std::string& elementType,
00255                                      const std::string& variableName,
00256                                      const std::string& variableType,
00257                                      const std::string& tableName ):
00258   m_elementType( Undefined ),
00259   m_isDependentTree(false),
00260   m_scopeName( "" ),
00261   m_variableName( variableName ),
00262   m_variableNameForSchema( "" ),
00263   m_variableType( variableType ),
00264   m_tableName( tableName ),
00265   m_columnNames(),
00266   m_subElements()
00267 {
00268   // Check here the element type
00269   m_elementType = elementTypeFromString( elementType );
00270   if(m_elementType == Dependency) m_isDependentTree = true;
00271 }
00272 
00273 ora::MappingElement::~MappingElement() {
00274 }
00275 
00276 namespace ora {
00277   void processTableHierarchy( const MappingElement& element,
00278                               std::set<std::string>& tableRegister,
00279                               std::vector<std::pair<std::string, std::string> >& tableList ){
00280     const std::string& tableName = element.tableName();
00281     std::set<std::string>::iterator iT = tableRegister.find( tableName );
00282     if( iT == tableRegister.end() ){
00283       if( element.columnNames().empty() ){
00284         throwException( "Mapping element for variable \""+element.variableName()+"\" does not specify column names.",
00285                         "MappingElement::tableHierarchy");
00286       }
00287       tableRegister.insert( tableName );
00288       tableList.push_back( std::make_pair(tableName,element.columnNames()[0]) );
00289     }
00290     for(MappingElement::const_iterator iEl = element.begin();
00291         iEl != element.end(); ++iEl ){
00292       processTableHierarchy( iEl->second, tableRegister, tableList );
00293     }
00294   }
00295 }
00296 
00297 std::vector<std::pair<std::string,std::string> >
00298 ora::MappingElement::tableHierarchy() const{
00299   std::set<std::string> involvedTables;
00300   std::vector<std::pair<std::string,std::string> > tableList;
00301   processTableHierarchy( *this, involvedTables,tableList );
00302   return tableList;
00303 }
00304 
00305 std::string ora::MappingElement::idColumn() const {
00306   if( m_columnNames.empty() ) throwException( "No column names found in the mapping element.",
00307                                               "MappingElement::idColumn");
00308   return m_columnNames.front();
00309 }
00310 
00311 std::string ora::MappingElement::pkColumn() const {
00312   size_t ind = 0;
00313   if( m_isDependentTree ) ind = 1;
00314   if( m_columnNames.size() < ind+1 )
00315     throwException( "Column names not found as expected in the mapping element.",
00316                     "MappingElement::idColumn");
00317   return m_columnNames.at( ind );
00318 }
00319 
00320 std::vector<std::string> ora::MappingElement::recordIdColumns() const {
00321   size_t ind = 0;
00322   if( m_isDependentTree ) ind = 1;
00323   size_t cols = m_columnNames.size();
00324   if( cols < ind+2 ){
00325     std::stringstream message;
00326     message <<"Column names for variable=\""<< m_variableName<<"\" of type=\""<<elementTypeAsString( m_elementType )<<"\" are not as expected.";
00327     throwException( message.str(),
00328                     "MappingElement::recordIdColumns");
00329   }
00330   std::vector<std::string> ret;
00331   for( size_t i=ind+1;i<cols;i++){
00332     ret.push_back( m_columnNames[i] );
00333   }
00334   return ret;
00335 }
00336 
00337 std::string ora::MappingElement::posColumn() const {
00338   size_t ind = 0;
00339   if( m_isDependentTree ) ind = 1;
00340   if( m_columnNames.size() < ind+2 )
00341     throwException( "Column names not found as expected in the mapping element.",
00342                     "MappingElement::posColumn");
00343   return m_columnNames.back();
00344 }
00345 
00346 ora::MappingElement&
00347 ora::MappingElement::appendSubElement( const std::string& elementType,
00348                                        const std::string& variableName,
00349                                        const std::string& variableType,
00350                                        const std::string& tableName )
00351 {
00352   // Check whether the current element type supports other subelements
00353   if ( ! ( m_elementType == Class ||
00354            m_elementType == Object ||
00355            m_elementType == Dependency ||
00356            m_elementType == Array ||
00357            m_elementType == CArray ||
00358            m_elementType == InlineCArray ||
00359            m_elementType == OraPointer ||
00360            m_elementType == OraArray ) ) {
00361     throwException( "Attempted to insert a sub-element under an element of type \"" +
00362                     ora::MappingElement::elementTypeAsString( m_elementType ) + "\"",
00363                     "MappingElement::appendSubElement" );
00364   }
00365   if(m_subElements.find( variableName )!=m_subElements.end()){
00366     throwException("Attribute name \""+variableName+"\" is already defined in the mapping element of variable \""+
00367                    m_variableName+"\".",
00368                    "MappingElement::appendSubElement");
00369   }
00370   
00371   MappingElement& newElement =
00372     m_subElements.insert( std::make_pair( variableName,ora::MappingElement( elementType,
00373                                                                             variableName,
00374                                                                             variableType,
00375                                                                             tableName ) ) ).first->second;
00376   newElement.m_isDependentTree = m_isDependentTree;
00377   if ( m_scopeName.empty() ) {
00378     newElement.m_scopeName = m_variableName;
00379   } else {
00380     newElement.m_scopeName = m_scopeName + "::" + m_variableName;
00381   }
00382   
00383   return newElement;
00384 }
00385 
00386 void
00387 ora::MappingElement::alterType( const std::string& elementType )
00388 {
00389   // Check here the element type
00390   if ( !  isValidMappingElementType( elementType ) ) {
00391     throwException( "\"" + elementType + "\" is not a supported mapping element type",
00392                     "MappingElement::alterType");
00393   }
00394   ElementType elementTypeCode = elementTypeFromString( elementType );
00395   if(m_elementType != elementTypeCode){
00396     m_elementType = elementTypeCode;      
00397     // clear sub elements when no supported by the new type specified
00398     if ( ! ( m_elementType == Class ||
00399              m_elementType == Object ||
00400              m_elementType == Dependency ||
00401              m_elementType == Array ||
00402              m_elementType == CArray ||
00403              m_elementType == InlineCArray ||
00404              m_elementType == OraPointer ||
00405              m_elementType == OraArray  ) ) {
00406       m_subElements.clear();
00407     }
00408   }
00409 }
00410 
00411 void
00412 ora::MappingElement::alterTableName( const std::string& tableName )
00413 {
00414   if ( tableName == m_tableName ) return;
00415 
00416   for ( iterator iElement = this->begin();
00417         iElement != this->end(); ++iElement ) {
00418     ora::MappingElement& subElement = iElement->second;
00419     if ( subElement.elementType() != Array &&
00420          subElement.elementType() != CArray &&
00421          subElement.elementType() != OraArray  ) {
00422       subElement.alterTableName( tableName );
00423     }
00424   }
00425   m_tableName = tableName;
00426 }
00427 
00428 void
00429 ora::MappingElement::setColumnNames( const std::vector< std::string >& columns )
00430 {
00431   m_columnNames = columns;
00432   if ( m_subElements.empty() ) return;
00433 }
00434 
00435 void ora::MappingElement::override(const MappingElement& source){
00436   if(variableType()==source.variableType() || elementType()==source.elementType())
00437   {
00438     alterType(MappingElement::elementTypeAsString(source.elementType()));
00439     alterTableName(source.tableName());
00440     setColumnNames(source.columnNames());
00441     for(iterator iel=begin();
00442         iel!=end();++iel){
00443       const_iterator iTarg = source.find(iel->first);
00444       if(iTarg!=source.end()){
00445         iel->second.override(iTarg->second);
00446       }
00447     }
00448   }  
00449 
00450 }
00451 
00452 void ora::MappingElement::printXML( std::ostream& outputStream, std::string indentation ) const {
00453   outputStream << indentation << "<"<<elementTypeString()<<" name=\""<<m_variableName<<"\" type=\""<<m_variableType<<
00454     "\" table=\""<<m_tableName<<"\"";
00455   if( !m_columnNames.empty()) {
00456     outputStream << " columns=\"";
00457     for( std::vector<std::string>::const_iterator iC=m_columnNames.begin(); iC != m_columnNames.end(); ++iC ){
00458       if( iC != m_columnNames.begin() ) outputStream << ",";
00459       outputStream << *iC;
00460     }
00461     outputStream << "\"";
00462   }
00463   outputStream << " >"<< std::endl;
00464   for( std::map< std::string, MappingElement >::const_iterator iM = m_subElements.begin();
00465        iM != m_subElements.end(); ++iM ){
00466     iM->second.printXML( outputStream, indentation+" " );
00467   }
00468   outputStream <<  indentation << "</"<<elementTypeString()<<">"<< std::endl;
00469 }
00470