GME  13
OCLType.cpp
Go to the documentation of this file.
00001 //###############################################################################################################################################
00002 //
00003 //      Object Constraint Language Generic Manager
00004 //      OCLType.h
00005 //
00006 //###############################################################################################################################################
00007 
00008 #include "Solve4786.h"
00009 #include "OCLType.h"
00010 
00011 #define NILNAMESPACE ""
00012 
00013 namespace OclMeta
00014 {
00015 
00016 //##############################################################################################################################################
00017 //
00018 //      F U N C T I O N S
00019 //
00020 //##############################################################################################################################################
00021 
00022         void DisposeCallMap( CallResultMap& mapArg )
00023         {
00024                 for ( CallResultMap::iterator i = mapArg.begin() ; i != mapArg.end() ; ++i )
00025                         if ( (*i).second.bIsValid )
00026                                 delete (*i).second.uResult.pFeature;
00027                         else
00028                                 delete (*i).second.uResult.pException;
00029                 mapArg.clear();
00030         }
00031 
00032         template < class TItem >
00033         TItem* DisposeVector( std::vector<TItem*>& vecArg, int iGetPos = -1 )
00034         {
00035                 TItem* pItem = NULL;
00036                 for ( unsigned int i = 0 ; i < vecArg.size() ; i++ )
00037                         if ( (int) i == iGetPos )
00038                                 pItem = vecArg[ i ];
00039                         else
00040                                 delete vecArg[ i ];
00041                 vecArg.clear();
00042                 return pItem;
00043         }
00044 
00045         int MatchParametralFeature( TypeManager* pManager, const OclSignature::ParametralFeature& signature, const OclSignature::ParametralFeature& feature )
00046         {
00047                 int iMatch = -1;
00048                 int iParamCount = signature.GetParameterCount();
00049                 if ( iParamCount >= feature.GetMinParameterCount() && iParamCount <= feature.GetParameterCount() ) {
00050                         if ( iParamCount == 0 )
00051                                         return 0;
00052                         for ( int i = 0 ; i < iParamCount ; i++ ) {
00053                                 int iIsA = pManager->IsTypeA( signature.GetParameter( i ).GetTypeName(), feature.GetParameter( i ).GetTypeName() );
00054                                 if ( iIsA == -1 ) {
00055                                         iMatch = -1;
00056                                         break;
00057                                 }
00058                                 else {
00059                                         if ( iMatch == -1 )
00060                                                 iMatch = 0;
00061                                         iMatch += iIsA;
00062                                 }
00063                         }
00064                 }
00065                 return iMatch;
00066         }
00067 
00068         template < class TFeature >
00069         TFeature* ReturnCallResult( const CallResult& callResult )
00070         {
00071                 if ( callResult.bIsValid )
00072                         return (TFeature*) callResult.uResult.pFeature;
00073                 else
00074                         throw OclCommon::Exception( *callResult.uResult.pException );
00075         }
00076 
00077         // recursion corrected: terge
00078         bool GetCallResult( const CallResultMap& mapArg, std::string/*const OclSignature::Feature*/& feature, CallResult& callResult )
00079         {
00080                 CallResultMap::const_iterator i = mapArg.find( feature/*.Print()*/ );
00081                 if ( i != mapArg.end() ) {
00082                         callResult = (*i).second;
00083                         return true;
00084                 }
00085                 return false;
00086         }
00087 
00088         template < class TParametralFeature, class TParametralSignature >
00089         void FilterParametralFeature( TypeManager* pManager, const TParametralSignature& signature, std::vector<TParametralFeature*>& vecArg, int iCodeAmbig, int iCodeExist, CallResult& callResult)
00090         {
00091                 int iPos = -1;
00092                 int iMatch = -1;
00093                 for ( unsigned int j = 0 ; j < vecArg.size() ; j++ ) {
00094                         int iMatch2 = 0;
00095                         try {
00096                                 iMatch2 = MatchParametralFeature( pManager, signature, *vecArg[ j ] );
00097                         } catch ( OclCommon::Exception ex ) {
00098                                 DisposeVector<TParametralFeature>( vecArg );
00099                                 throw ex;
00100                         }
00101                         if ( iMatch2 != -1 ) {
00102                                 if ( iMatch == -1 || iMatch2 < iMatch ) {
00103                                         iMatch = iMatch2;
00104                                         iPos = (int) j;
00105                                 }
00106                                 else if ( iMatch == iMatch2 && ! vecArg[ j ]->IsIdentical( *vecArg[ iPos ] ) ) {
00107                                         iPos = -1;
00108                                         callResult.bIsValid = false;
00109                                         callResult.uResult.pException = new OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, iCodeAmbig, signature.Print() );
00110                                         break;
00111                                 }
00112                         }
00113                 }
00114                 TParametralFeature* pParametralFeature = DisposeVector<TParametralFeature>( vecArg, iPos );
00115                 if ( ! pParametralFeature ) {
00116                         callResult.bIsValid = false;
00117                         callResult.uResult.pException = new OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, iCodeExist, signature.Print() );
00118                 }
00119                 else {
00120                         callResult.bIsValid = true;
00121                         callResult.uResult.pFeature = (Feature*)pParametralFeature;
00122                 }
00123         }
00124 
00125         template < class TTypeableFeature, class TTypeableSignature >
00126         void FilterTypeableFeature( const TTypeableSignature& signature, std::vector<TTypeableFeature*>& vecArg, int iCodeAmbig, int iCodeExist, CallResult& callResult )
00127         {
00128                 if ( vecArg.size() > 1 ) {
00129                         DisposeVector<TTypeableFeature>( vecArg );
00130                         callResult.bIsValid = false;
00131                         callResult.uResult.pException = new OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, iCodeAmbig, signature.Print() );
00132                         return;
00133                 }
00134                 if ( vecArg.empty() ) {
00135                         callResult.bIsValid = false;
00136                         callResult.uResult.pException = new OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, iCodeExist, signature.Print() );
00137                         return;
00138                 }
00139                 callResult.bIsValid = true;
00140                 callResult.uResult.pFeature = vecArg[ 0 ];
00141         }
00142 
00143         template< class TFeature , class TFeatureSignature >
00144         bool FilterBaseType( TypeManager* pManager, const StringVector& vecSuperTypes, const TFeatureSignature& signature, std::vector<TFeature*>& vecArg, int iCodeExist, CallResult& callResult )
00145         {
00146                 for ( unsigned int i = 0 ; i < vecSuperTypes.size() ; i++ ) {
00147                         try {
00148                                 std::shared_ptr<Type> pType = pManager->GetType( vecSuperTypes[ i ], NILNAMESPACE );
00149                                 callResult = pType->GetResults( signature );
00150                                 if ( callResult.bIsValid )
00151                                         vecArg.push_back( (TFeature*) callResult.uResult.pFeature );
00152                                 else {
00153                                         if ( callResult.uResult.pException->GetCode() == iCodeExist )
00154                                                 delete callResult.uResult.pException;
00155                                         else {
00156                                                 DisposeVector<TFeature>( vecArg );
00157                                                 return false;
00158                                         }
00159                                 }
00160                         }
00161                         catch( OclCommon::Exception ex ) {
00162                                 DisposeVector<TFeature>( vecArg );
00163                                 throw ex;
00164                         }
00165                 }
00166                 return true;
00167         }
00168 
00169 //##############################################################################################################################################
00170 //
00171 //      C L A S S : OclMeta::TypeManager
00172 //
00173 //##############################################################################################################################################
00174 
00175         TypeManager::TypeManager( OclImplementation::TypeFactory* pTypeFactory, OclImplementation::OperatorFactory* pOperatorFactory, OclImplementation::FunctionFactory* pFunctionFactory, OclImplementation::ConstraintDefinitionFactory* pCDFactory )
00176                 : m_pTypeFactory( pTypeFactory ), m_pOperatorFactory( pOperatorFactory ), m_pFunctionFactory( pFunctionFactory ), m_pDefinitionFactory( pCDFactory )
00177         {
00178                 pTypeFactory->m_pTypeManager = this;
00179                 pOperatorFactory->m_pTypeManager = this;
00180                 pFunctionFactory->m_pTypeManager = this;
00181                 m_pDefinitionFactory->m_pTypeManager = this;
00182         }
00183 
00184         TypeManager::~TypeManager()
00185         {
00186                 Clear();
00187                 delete m_pTypeFactory;
00188                 delete m_pOperatorFactory;
00189                 delete m_pFunctionFactory;
00190                 delete m_pDefinitionFactory;
00191         }
00192 
00193         OclImplementation::ConstraintDefinitionFactory* TypeManager::GetDefinitionFactory() const
00194         {
00195                 return m_pDefinitionFactory;
00196         }
00197 
00198         void TypeManager::ClearTypes()
00199         {
00200                 m_mapTypes.clear();
00201         }
00202 
00203         void TypeManager::ClearDynamicTypes()
00204         {
00205                 TypeResultMap mapTypes = m_mapTypes;
00206                 m_mapTypes.clear();
00207                 for ( TypeResultMap::iterator i = mapTypes.begin() ; i != mapTypes.end() ; ++i )
00208                         if ( ! (*i).second.bIsValid )
00209                                 i->second.pException.reset();
00210                         else
00211                                 if ( (*i).second.pType->IsDynamic() )
00212                                         i->second.pType.reset();
00213                                 else
00214                                         m_mapTypes.insert( TypeResultMap::value_type( (*i).first, std::move((*i).second) ) );
00215         }
00216 
00217         void TypeManager::ClearGlobals()
00218         {
00219                 DisposeCallMap( m_mapOperators );
00220                 DisposeCallMap( m_mapFunctions );
00221         }
00222 
00223         void TypeManager::Clear()
00224         {
00225                 ClearTypes();
00226                 ClearGlobals();
00227         }
00228 
00229         std::shared_ptr<Type> TypeManager::GetType( const std::string& strName, const std::string& strNSpace  )
00230         {
00231                 std::string nameResult;
00232                 TypeResultMap::iterator i = m_mapTypes.find( strName );
00233                 if ( i != m_mapTypes.end() ) {
00234                         if ( (*i).second.bIsValid )
00235                                 return (*i).second.pType;
00236                         else
00237                                 throw OclCommon::Exception( *(*i).second.pException );
00238                 }
00239                 TypeVector vecTypes;
00240                 TypeResult typeResult;
00241                 try {
00242                         m_pTypeFactory->GetTypes( strName, strNSpace, vecTypes, nameResult );
00243                         if ( vecTypes.empty() ) {
00244                                 typeResult.bIsValid = false;
00245                                 typeResult.pException = std::shared_ptr<OclCommon::Exception>(new OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, EX_TYPE_DOESNT_EXIST, strName ));
00246                         }
00247                         else {
00248                                 if ( vecTypes.size() > 1 ) {
00249                                         typeResult.bIsValid = false;
00250                                         typeResult.pException = std::shared_ptr<OclCommon::Exception>(new OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, EX_TYPE_AMBIGUOUS, strName ));
00251                                 }
00252                                 else {
00253                                         typeResult.bIsValid = true;
00254                                         typeResult.pType = std::shared_ptr<Type>(vecTypes[ 0 ].release());
00255                                 }
00256                         }
00257                 }
00258                 catch ( OclCommon::Exception ex ) {
00259                         typeResult.bIsValid = false;
00260                         typeResult.pException = std::shared_ptr<OclCommon::Exception>(new OclCommon::Exception( ex ));
00261                 }
00262                 TypeResultMap::iterator it = m_mapTypes.insert( TypeResultMap::value_type( std::move(nameResult), std::move(typeResult) ) ).first; 
00263                 // WAS: m_mapTypes.insert( TypeResultMap::value_type( strName, typeResult ) );
00264                 RegisterType( typeResult );
00265                 if ( typeResult.bIsValid )
00266                         return typeResult.pType;
00267                 else
00268                         throw OclCommon::Exception( *typeResult.pException );
00269         }
00270 
00271         int TypeManager::IsTypeAR( const std::string& strName1, const std::string& strName2, int iLevel )
00272         {
00273                 std::shared_ptr<Type> pType1 = GetType( strName1, NILNAMESPACE );
00274                 if ( pType1->GetName() == strName2 )
00275                         return iLevel;
00276                 const StringVector& vecSuperTypes = pType1->GetSuperTypeNames();
00277                 int iIsA = -1;
00278                 for ( unsigned int i = 0 ; i < vecSuperTypes.size() ; i++ ) {
00279                         int iIsA2 = IsTypeAR( vecSuperTypes[ i ], strName2, iLevel + 1 );
00280                         if ( iIsA2 != -1 && ( iIsA == -1 || iIsA2 < iIsA ) )
00281                                 iIsA = iIsA2;
00282                 }
00283                 return iIsA;
00284         }
00285 
00286         int TypeManager::IsTypeA( const std::string& strName1, const std::string& strName2 )
00287         {
00288                 std::shared_ptr<Type> pType2 = GetType( strName2, NILNAMESPACE );
00289                 return IsTypeAR( strName1, pType2->GetName(), 0 );
00290         }
00291 
00292         int TypeManager::GetTypeDistance( const std::string& strName )
00293         {
00294                 std::shared_ptr<Type> pType = GetType( ( strName.empty() ) ? "ocl::Any" : strName, NILNAMESPACE );
00295                 const StringVector& vecSuperTypes = pType->GetSuperTypeNames();
00296                 if ( vecSuperTypes.empty() )
00297                         return 0;
00298                 int iDistance = -1;
00299                 for ( unsigned int i = 0 ; i < vecSuperTypes.size() ; i++ ) {
00300                         int iDistance2 = GetTypeDistance( vecSuperTypes[ i ] );
00301                         if ( iDistance == -1 || iDistance2 < iDistance )
00302                                 iDistance = iDistance2 + 1;
00303                 }
00304                 return iDistance;
00305         }
00306 
00307         std::string TypeManager::GetTypeBaseR( const std::string& strName1, const std::string& strName2 )
00308         {
00309                 if ( strName1 == "ocl::Any" )
00310                                 return strName1;
00311                 StringVector vecTypes;
00312                 const StringVector& vecSuperTypes = GetType( strName1, NILNAMESPACE )->GetSuperTypeNames();
00313                 unsigned int i;
00314                 for ( i = 0 ; i < vecSuperTypes.size() ; i++ )
00315                         vecTypes.push_back( GetTypeBase( vecSuperTypes[ i ], strName2 ) );
00316                 int iIsA = -1;
00317                 std::string strResult = "ocl::Any";
00318                 for ( i = 0 ; i < vecTypes.size() ; i++ ) {
00319                         int iIsA2 = GetTypeDistance( vecTypes[ i ] );
00320                         if ( iIsA2 != -1 && ( iIsA == -1 || iIsA2 < iIsA ) ) {
00321                                 strResult = vecTypes[ i ];
00322                                 iIsA = iIsA2;
00323                         }
00324                 }
00325                 return strResult;
00326         }
00327 
00328         std::string TypeManager::GetTypeBase( const std::string& strName1, const std::string& strName2 )
00329         {
00330                 if ( IsTypeA( strName1, strName2 ) >= 0 )
00331                                 return strName2;
00332                 if ( IsTypeA( strName2, strName1 ) >= 0 )
00333                                 return strName1;
00334                 std::string strBase1 = GetTypeBaseR( strName1, strName2 );
00335                 std::string strBase2 = GetTypeBaseR( strName2, strName1 );
00336                 if ( strBase1 == "ocl::Any" )
00337                                 return strBase2;
00338                 if ( strBase2 == "ocl::Any" )
00339                                 return strBase1;
00340                 return ( GetTypeDistance( strBase1 ) < GetTypeDistance( strBase2 ) ) ? strBase1 : strBase2;
00341         }
00342 
00343         TypeSeq TypeManager::GetTypeBase( const TypeSeq& vecType1, const TypeSeq& vecType2 )
00344         {
00345                 if ( vecType2.size() < vecType1.size() )
00346                         return GetTypeBase( vecType2, vecType1 );
00347                 TypeSeq vecType;
00348                 for ( unsigned int i = 0 ; i < vecType1.size() ; i++ )
00349                         vecType.push_back( GetTypeBase( vecType1[ i ], vecType2[ i ] ) );
00350                 return vecType;
00351         }
00352 
00353         bool TypeManager::IsTypeA( const TypeSeq& vecType1, const TypeSeq& vecType2 )
00354         {
00355                 // terge ?? 
00356                 if ( vecType2.size() < vecType1.size() )
00357                         return false;
00358                 for ( unsigned int i = 0 ; i < vecType1.size() ; i++ )
00359                         if ( IsTypeA( vecType1[ i ], vecType2[ i ] ) < 0 )
00360                                 return false;
00361                 return true;
00362         }
00363 
00364         Operator* TypeManager::GetOperator( const OclSignature::Operator& signature )
00365         {
00366                 CallResult callResult;
00367                 callResult.uResult.pException = NULL;
00368                 std::string signo = signature.Print();
00369 
00370                 if ( GetCallResult( m_mapOperators, signo/*signature*/, callResult ) )
00371                         return ReturnCallResult<Operator>( callResult );
00372 
00373                 OperatorVector vecOperators;
00374                 try {
00375                         m_pOperatorFactory->GetFeatures( signature, vecOperators );
00376                         FilterParametralFeature<Operator,OclSignature::Operator>( this, signature, vecOperators, EX_OPERATOR_AMBIGUOUS, EX_OPERATOR_DOESNT_EXIST, callResult );
00377                 }
00378                 catch ( OclCommon::Exception ex ) {
00379                         DisposeVector<Operator>( vecOperators );
00380                         callResult.bIsValid = false;
00381                         callResult.uResult.pException = new OclCommon::Exception( ex );
00382                 }
00383 
00384                 m_mapOperators.insert( CallResultMap::value_type( signature.Print(), callResult ) );
00385                 RegisterFeature( callResult );
00386                 return ReturnCallResult<Operator>( callResult );
00387         }
00388 
00389         Function* TypeManager::GetFunction( const OclSignature::Function& signature )
00390         {
00391                 CallResult callResult;
00392                 callResult.uResult.pException = NULL;
00393                 std::string signo = signature.Print();
00394 
00395                 if ( GetCallResult( m_mapFunctions, signo/*signature*/, callResult ) )
00396                         return ReturnCallResult<Function>( callResult );
00397 
00398                 FunctionVector vecFunctions;
00399                 try {
00400                         m_pFunctionFactory->GetFeatures( signature, vecFunctions );
00401                         FilterParametralFeature<Function,OclSignature::Function>( this, signature, vecFunctions, EX_FUNCTION_AMBIGUOUS, EX_FUNCTION_DOESNT_EXIST, callResult );
00402                 }
00403                 catch ( OclCommon::Exception ex ) {
00404                         DisposeVector<Function>( vecFunctions );
00405                         callResult.bIsValid = false;
00406                         callResult.uResult.pException = new OclCommon::Exception( ex );
00407                 }
00408 
00409                 m_mapFunctions.insert( CallResultMap::value_type( signature.Print(), callResult ) );
00410                 RegisterFeature( callResult );
00411                 return ReturnCallResult<Function>( callResult );
00412         }
00413 
00414         void TypeManager::RegisterFeature( CallResult& callResult )
00415         {
00416                 if ( callResult.bIsValid ) {
00417                         OclSignature::Feature::FeatureKind eKind = callResult.uResult.pFeature->GetKind();
00418                         switch ( eKind ) {
00419                                 case OclSignature::Feature::FK_OPERATOR                 :
00420                                         {
00421                                                 OclImplementation::Operator* impl = ( (Operator*) callResult.uResult.pFeature )->GetImplementation();
00422                                                 if (impl != NULL)
00423                                                         impl->m_pTypeManager = this;
00424                                         }
00425                                         break;
00426                                 case OclSignature::Feature::FK_FUNCTION                 :
00427                                         {
00428                                                 OclImplementation::Function* impl = ( (Function*) callResult.uResult.pFeature )->GetImplementation();
00429                                                 if (impl != NULL)
00430                                                         impl->m_pTypeManager = this;
00431                                         }
00432                                         break;
00433                                 case OclSignature::Feature::FK_ATTRIBUTE                :
00434                                         {
00435                                                 OclImplementation::Attribute* impl = ( (Attribute*) callResult.uResult.pFeature )->GetImplementation();
00436                                                 if (impl != NULL)
00437                                                         impl->m_pTypeManager = this;
00438                                         }
00439                                         break;
00440                                 case OclSignature::Feature::FK_ASSOCIATION              :
00441                                         {
00442                                                 OclImplementation::Association* impl = ( (Association*) callResult.uResult.pFeature )->GetImplementation();
00443                                                 if (impl != NULL)
00444                                                         impl->m_pTypeManager = this;
00445                                         }
00446                                         break;
00447                                 case OclSignature::Feature::FK_METHOD                   :
00448                                         {
00449                                                 OclImplementation::Method* impl = ( (Method*) callResult.uResult.pFeature )->GetImplementation();
00450                                                 if (impl != NULL)
00451                                                         impl->m_pTypeManager = this;
00452                                         }
00453                                         break;
00454                                 case OclSignature::Feature::FK_ITERATOR                 :
00455                                         {
00456                                                 OclImplementation::Iterator* impl = ( (Iterator*) callResult.uResult.pFeature )->GetImplementation();
00457                                                 if (impl != NULL)
00458                                                         impl->m_pTypeManager = this;
00459                                         }
00460                                         break;
00461                         }
00462                 }
00463         }
00464 
00465         void TypeManager::RegisterType( TypeResult& typeResult )
00466         {
00467                 if ( typeResult.bIsValid ) {
00468                         typeResult.pType->m_pTypeManager = this;
00469                         typeResult.pType->m_pAttributeFactory->m_pTypeManager = this;
00470                         typeResult.pType->m_pAssociationFactory->m_pTypeManager = this;
00471                         typeResult.pType->m_pMethodFactory->m_pTypeManager = this;
00472                         if ( typeResult.pType->IsCompound() )
00473                                 ( (CompoundType*) typeResult.pType.get() )->m_pIteratorFactory->m_pTypeManager = this;
00474                 }
00475         }
00476 
00477 //##############################################################################################################################################
00478 //
00479 //      C L A S S : OclMeta::Type
00480 //
00481 //##############################################################################################################################################
00482 
00483         Type::Type( const std::string& strName, const StringVector& vecSuperTypes, OclImplementation::AttributeFactory* pAttributeFactory, OclImplementation::AssociationFactory* pAssociationFactory, OclImplementation::MethodFactory* pMethodFactory, bool bDynamic )
00484                 : m_strName( strName ), m_vecSuperTypes( vecSuperTypes ), m_pAttributeFactory( pAttributeFactory ), m_pAssociationFactory( pAssociationFactory ), m_pMethodFactory( pMethodFactory ), m_bDynamic( bDynamic )
00485         {
00486         }
00487 
00488         Type::~Type()
00489         {
00490                 DisposeCallMap( m_mapAttributes );
00491                 DisposeCallMap( m_mapAssociations );
00492                 DisposeCallMap( m_mapMethods );
00493                 delete m_pAttributeFactory;
00494                 delete m_pAssociationFactory;
00495                 delete m_pMethodFactory;
00496         }
00497 
00498         bool Type::IsDynamic() const
00499         {
00500                 return m_bDynamic;
00501         }
00502 
00503         std::string Type::GetName() const
00504         {
00505                 return m_strName;
00506         }
00507 
00508         const StringVector& Type::GetSuperTypeNames() const
00509         {
00510                 return m_vecSuperTypes;
00511         }
00512 
00513         TypeManager* Type::GetTypeManager() const
00514         {
00515                 return m_pTypeManager;
00516         }
00517 
00518         bool Type::IsCompound() const
00519         {
00520                 return false;
00521         }
00522 
00523         Attribute* Type::GetAttribute( const OclSignature::Attribute& signature )
00524         {
00525                 CallResult callResult;
00526                 std::string signo = signature.Print();
00527 
00528                 if ( GetCallResult( m_mapAttributes, signo/*signature*/, callResult ) )
00529                         return ReturnCallResult<Attribute>( callResult );
00530 
00531                 callResult = GetResults( signature );
00532 
00533                 m_mapAttributes.insert( CallResultMap::value_type( signature.Print(), callResult ) );
00534                 m_pTypeManager->RegisterFeature( callResult );
00535                 return ReturnCallResult<Attribute>( callResult );
00536         }
00537 
00538         Association* Type::GetAssociation( const OclSignature::Association& signature )
00539         {
00540                 CallResult callResult;
00541                 std::string signo = signature.Print();
00542 
00543                 if ( GetCallResult( m_mapAssociations, signo/*signature*/, callResult ) )
00544                         return ReturnCallResult<Association>( callResult );
00545 
00546                 callResult = GetResults( signature );
00547 
00548                 m_mapAssociations.insert( CallResultMap::value_type( signature.Print(), callResult ) );
00549                 m_pTypeManager->RegisterFeature( callResult );
00550                 return ReturnCallResult<Association>( callResult );
00551         }
00552 
00553         Method* Type::GetMethod( const OclSignature::Method& signature )
00554         {
00555                 CallResult callResult;
00556                 std::string signo = signature.Print();
00557 
00558                 if ( GetCallResult( m_mapMethods, signo/*signature*/, callResult ) )
00559                         return ReturnCallResult<Method>( callResult );
00560 
00561                 callResult = GetResults( signature );
00562 
00563                 m_mapMethods.insert( CallResultMap::value_type( signature.Print(), callResult ) );
00564                 m_pTypeManager->RegisterFeature( callResult );
00565                 return ReturnCallResult<Method>( callResult );
00566         }
00567 
00568         CallResult Type::GetResults( const OclSignature::Attribute& signature )
00569         {
00570                 CallResult callResult;
00571 
00572                 AttributeVector vecAttributes;
00573                 try {
00574                         m_pAttributeFactory->GetFeatures( signature, vecAttributes );
00575                         m_pTypeManager->GetDefinitionFactory()->GetFeatures( signature, vecAttributes );
00576 
00577                         FilterTypeableFeature<Attribute,OclSignature::Attribute>( signature, vecAttributes, EX_ATTRIBUTE_AMBIGUOUS, EX_ATTRIBUTE_DOESNT_EXIST, callResult );
00578                         if ( callResult.bIsValid || callResult.uResult.pException->GetCode() != EX_ATTRIBUTE_DOESNT_EXIST )
00579                                 return callResult;
00580                         else
00581                                 delete callResult.uResult.pException;
00582 
00583                         if ( ! FilterBaseType<Attribute,OclSignature::Attribute>( m_pTypeManager, m_vecSuperTypes, signature, vecAttributes, EX_ATTRIBUTE_DOESNT_EXIST, callResult ) )
00584                                 return callResult;
00585 
00586                         FilterTypeableFeature<Attribute,OclSignature::Attribute>( signature, vecAttributes, EX_ATTRIBUTE_AMBIGUOUS, EX_ATTRIBUTE_DOESNT_EXIST, callResult );
00587                 }
00588                 catch ( OclCommon::Exception ex ) {
00589                         DisposeVector<Attribute>( vecAttributes );
00590                         callResult.bIsValid = false;
00591                         callResult.uResult.pException = new OclCommon::Exception( ex );
00592                 }
00593 
00594                 return callResult;
00595         }
00596 
00597         CallResult Type::GetResults( const OclSignature::Association& signature )
00598         {
00599                 CallResult callResult;
00600 
00601                 AssociationVector vecAssociations;
00602                 try {
00603                         m_pAssociationFactory->GetFeatures( signature, vecAssociations );
00604 
00605                         FilterTypeableFeature<Association,OclSignature::Association>( signature, vecAssociations, EX_ASSOCIATION_AMBIGUOUS, EX_ASSOCIATION_DOESNT_EXIST, callResult );
00606                         if ( callResult.bIsValid || callResult.uResult.pException->GetCode() != EX_ASSOCIATION_DOESNT_EXIST )
00607                                 return callResult;
00608                         else
00609                                 delete callResult.uResult.pException;
00610 
00611                         if ( ! FilterBaseType<Association,OclSignature::Association>( m_pTypeManager, m_vecSuperTypes, signature, vecAssociations, EX_ASSOCIATION_DOESNT_EXIST, callResult ) )
00612                                 return callResult;
00613 
00614                         FilterTypeableFeature<Association,OclSignature::Association>( signature, vecAssociations, EX_ASSOCIATION_AMBIGUOUS, EX_ASSOCIATION_DOESNT_EXIST, callResult );
00615                         }
00616                 catch ( OclCommon::Exception ex ) {
00617                         DisposeVector<Association>( vecAssociations );
00618                         callResult.bIsValid = false;
00619                         callResult.uResult.pException = new OclCommon::Exception( ex );
00620                 }
00621 
00622                 return callResult;
00623         }
00624 
00625         CallResult Type::GetResults( const OclSignature::Method& signature )
00626         {
00627                 CallResult callResult;
00628 
00629                 MethodVector vecMethods;
00630                 try {
00631                         m_pMethodFactory->GetFeatures( signature, vecMethods);
00632                         m_pTypeManager->GetDefinitionFactory()->GetFeatures( signature, vecMethods );
00633 
00634                         FilterParametralFeature<Method,OclSignature::Method>( m_pTypeManager, signature, vecMethods, EX_METHOD_AMBIGUOUS, EX_METHOD_DOESNT_EXIST, callResult );
00635                         if ( callResult.bIsValid || callResult.uResult.pException->GetCode() != EX_METHOD_DOESNT_EXIST )
00636                                 return callResult;
00637                         else
00638                                 delete callResult.uResult.pException;
00639 
00640                         if ( ! FilterBaseType<Method,OclSignature::Method>( m_pTypeManager, m_vecSuperTypes, signature, vecMethods, EX_METHOD_DOESNT_EXIST, callResult ) )
00641                                 return callResult;
00642 
00643                         FilterParametralFeature<Method,OclSignature::Method>( m_pTypeManager, signature, vecMethods, EX_METHOD_AMBIGUOUS, EX_METHOD_DOESNT_EXIST, callResult );
00644                 }
00645                 catch ( OclCommon::Exception ex ) {
00646                         DisposeVector<Method>( vecMethods );
00647                         callResult.bIsValid = false;
00648                         callResult.uResult.pException = new OclCommon::Exception( ex );
00649                 }
00650 
00651                 return callResult;
00652         }
00653 
00654         CallResult Type::GetResults( const OclSignature::Iterator& signature )
00655         {
00656                 CallResult callResult;
00657                 callResult.bIsValid = false;
00658                 callResult.uResult.pException = new OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, EX_ITERATOR_DOESNT_EXIST, signature.Print() );
00659                 return callResult;
00660         }
00661 
00662 //##############################################################################################################################################
00663 //
00664 //      C L A S S : OclMeta::CompoundType
00665 //
00666 //##############################################################################################################################################
00667 
00668         CompoundType::CompoundType( const std::string& strName, const StringVector& vecSuperTypes, OclImplementation::AttributeFactory* pAttributeFactory, OclImplementation::AssociationFactory* pAssociationFactory, OclImplementation::MethodFactory* pMethodFactory, OclImplementation::IteratorFactory* pIteratorFactory, bool bDynamic )
00669                 : Type( strName, vecSuperTypes, pAttributeFactory, pAssociationFactory, pMethodFactory, bDynamic ), m_pIteratorFactory( pIteratorFactory )
00670         {
00671         }
00672 
00673         CompoundType::~CompoundType()
00674         {
00675                 DisposeCallMap( m_mapIterators );
00676                 delete m_pIteratorFactory;
00677         }
00678 
00679         bool CompoundType::IsCompound() const
00680         {
00681                 return true;
00682         }
00683 
00684         Iterator* CompoundType::GetIterator(int level, const OclSignature::Iterator& signature )
00685         {
00686                 CallResult callResult;
00687 
00688                 // recursion corrected: terge
00689                 char signoStr[100];
00690                 std::string signo = signature.Print();
00691 #ifdef _WIN32
00692                 _itoa_s(level, signoStr, sizeof(signoStr), 10);  
00693 #else
00694                 sprintf( signoStr, "%ld", level );
00695 #endif
00696                 signo += signoStr;
00697 
00698                 if ( GetCallResult( m_mapIterators, signo/*signature*/, callResult ) )
00699                         return ReturnCallResult<Iterator>( callResult );
00700 
00701                 callResult = GetResults( signature );
00702 
00703                 m_mapIterators.insert( CallResultMap::value_type( signo/*signature.Print()*/, callResult ) );
00704                 GetTypeManager()->RegisterFeature( callResult );
00705                 return ReturnCallResult<Iterator>( callResult );
00706         }
00707 
00708         CallResult CompoundType::GetResults( const OclSignature::Iterator& signature )
00709         {
00710                 CallResult callResult;
00711 
00712                 IteratorVector vecIterators;
00713                 try {
00714                         m_pIteratorFactory->GetFeatures( signature, vecIterators);
00715 
00716                         FilterParametralFeature<Iterator,OclSignature::Iterator>( GetTypeManager(), signature, vecIterators, EX_ITERATOR_AMBIGUOUS, EX_ITERATOR_DOESNT_EXIST, callResult );
00717                         if ( callResult.bIsValid || callResult.uResult.pException->GetCode() != EX_ITERATOR_DOESNT_EXIST )
00718                                 return callResult;
00719                         else
00720                                 delete callResult.uResult.pException;
00721 
00722                         if ( ! FilterBaseType<Iterator,OclSignature::Iterator>( GetTypeManager(), GetSuperTypeNames(), signature, vecIterators, EX_ITERATOR_DOESNT_EXIST, callResult ) )
00723                                 return callResult;
00724 
00725                         FilterParametralFeature<Iterator,OclSignature::Iterator>( GetTypeManager(), signature, vecIterators, EX_ITERATOR_AMBIGUOUS, EX_ITERATOR_DOESNT_EXIST, callResult );
00726                 }
00727                 catch ( OclCommon::Exception ex ) {
00728                         DisposeVector<Iterator>( vecIterators );
00729                         callResult.bIsValid = false;
00730                         callResult.uResult.pException = new OclCommon::Exception( ex );
00731                 }
00732 
00733                 return callResult;
00734         }
00735 
00736 }; // namespace OclMeta