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