GME  13
OCLGMECMFacade.cpp
Go to the documentation of this file.
00001 //###############################################################################################################################################
00002 //
00003 //      Object Constraint Language Generic Manager
00004 //      OCLGMECMFacade.cpp
00005 //
00006 //###############################################################################################################################################
00007 #include "Solve4786.h"
00008 #include "OCLGMECMFacade.h"
00009 #include "GMEViolationDialog.h"
00010 #include "GMESmallMessageBox.h"
00011 #include "OCLTypeExGMECM.h"
00012 #include "OCLCommonEx.h"
00013 #include "OCLObjectExBasic.h"
00014 #include "OCLObjectExGME.h"
00015 #include <algorithm>
00016 
00017 namespace OclGmeCM
00018 {
00019 
00020 //##############################################################################################################################################
00021 //
00022 //      C L A S S : OclGmeCM::ConstraintDefinitionFactory <<< + OclImplementation::ConstraintDefinitionFactory
00023 //
00024 //==============================================================================================================================================
00025 //
00026 //      D E S C R I P T I O N :
00027 //
00028 //##############################################################################################################################################
00029 
00030         class ConstraintAttribute
00031                 : public OclImplementation::Attribute
00032         {
00033                 private :
00034                         OclGme::SpConstraintFunction    m_spFunction;
00035                         CComPtr<IMgaProject>                    m_spProject;
00036 
00037                 public :
00038                         ConstraintAttribute( CComPtr<IMgaProject> spProject, OclGme::SpConstraintFunction spFunction )
00039                                 : m_spFunction( spFunction ), m_spProject( spProject )
00040                         {
00041                         }
00042 
00043                         void operator()()
00044                         {
00045                                 if ( ! m_spFunction.Ptr() || m_spFunction->GetState() < Ocl::Constraint::CS_CHECK_DEPENDENCY_SUCCEEDED )
00046                                         ThrowException( "Constraint attribute definition cannot be evaluated." );
00047                                 OclTree::ObjectContextStack context;
00048                                 context.AddVariable( "project", CREATE_GMEPROJECT( GetTypeManager(), m_spProject ) );
00049                                 context.AddVariable( "self", GetThis() );
00050                                 SetResult( m_spFunction->Evaluate( context ) );
00051                         }
00052         };
00053 
00054         class ConstraintMethod
00055                 : public OclImplementation::Method
00056         {
00057                 private :
00058                         OclGme::SpConstraintFunction    m_spFunction;
00059                         CComPtr<IMgaProject>                    m_spProject;
00060 
00061                 public :
00062                         ConstraintMethod( CComPtr<IMgaProject> spProject, OclGme::SpConstraintFunction spFunction )
00063                                 : m_spFunction( spFunction ), m_spProject( spProject )
00064                         {
00065                         }
00066 
00067                         OclTree::ViolationVector GetViolations() 
00068                         {
00069                                 return m_spFunction->GetViolations();
00070                         }
00071 
00072                         void ClearViolations()
00073                         {
00074                                 m_spFunction->ClearViolations();
00075                         }
00076 
00077 
00078                         void operator()()
00079                         {
00080 
00081                                 if ( ! m_spFunction.Ptr() || m_spFunction->GetState() < Ocl::Constraint::CS_CHECK_DEPENDENCY_SUCCEEDED )
00082                                         ThrowException( "Constraint method definition cannot be evaluated." );
00083                                 OclTree::ObjectContextStack context;
00084                                 context.AddVariable( "project", CREATE_GMEPROJECT( GetTypeManager(), m_spProject ) );
00085                                 context.AddVariable( "self", GetThis() );
00086                                 OclCommon::FormalParameterVector vecParameters = m_spFunction->GetFormalParameters();
00087                                 for ( unsigned int i = 0 ; i < vecParameters.size() ; i++ )
00088                                         context.AddVariable( vecParameters[ i ].GetName(), ( (int) i >= GetArgumentCount() ) ? OclMeta::Object::UNDEFINED : GetArgument( i ) );
00089                                 SetResult( m_spFunction->Evaluate( context ) );
00090                         }
00091         };
00092 
00093         class ConstraintDefinitionFactory
00094                 : public OclImplementation::ConstraintDefinitionFactory
00095         {
00096                 public :
00097                         Facade* m_pFacade;
00098 
00099                         virtual void GetFeatures( const OclSignature::Attribute& signature, OclMeta::AttributeVector& vecFeatures )
00100                         {
00101                                 OclGme::ConstraintFunctionVector vecFunctions = m_pFacade->m_vecMetaConstraintFunctions;
00102                                 for ( unsigned int i = 0 ; i < vecFunctions.size() ; i++ ) {
00103                                         if ( vecFunctions[ i ]->IsValid() && m_pFacade->GetTreeManager()->GetTypeManager()->IsTypeA( signature.GetTypeName(), vecFunctions[ i ]->GetContextType() ) >= 0 )
00104                                                 if ( vecFunctions[ i ]->GetName() == signature.GetName() && vecFunctions[ i ]->GetStereotype() == Ocl::Constraint::CS_ATTRIBUTEDEF )
00105                                                         vecFeatures.push_back( new OclMeta::Attribute( signature.GetName(), CreateReturnType( vecFunctions[ i ]->GetReturnType() ), new ConstraintAttribute( m_pFacade->GetProject(), vecFunctions[ i ] ), true, true ) );
00106                                 }
00107                                 vecFunctions = m_pFacade->m_vecUserConstraintFunctions;
00108                                 for (  unsigned int i = 0 ; i < vecFunctions.size() ; i++ ) {
00109                                         if ( vecFunctions[ i ]->IsValid() && m_pFacade->GetTreeManager()->GetTypeManager()->IsTypeA( signature.GetTypeName(), vecFunctions[ i ]->GetContextType() ) >= 0 )
00110                                                 if ( vecFunctions[ i ]->GetName() == signature.GetName() && vecFunctions[ i ]->GetStereotype() == Ocl::Constraint::CS_ATTRIBUTEDEF )
00111                                                         vecFeatures.push_back( new OclMeta::Attribute( signature.GetName(), CreateReturnType( vecFunctions[ i ]->GetReturnType() ), new ConstraintAttribute( m_pFacade->GetProject(), vecFunctions[ i ] ), true, true ) );
00112                                 }
00113                         }
00114 
00115                         virtual void GetFeatures( const OclSignature::Method& signature, OclMeta::MethodVector& vecFeatures )
00116                         {
00117                                 OclGme::ConstraintFunctionVector vecFunctions = m_pFacade->m_vecMetaConstraintFunctions;
00118                                 for ( unsigned int i = 0 ; i < vecFunctions.size() ; i++ ) {
00119                                         if ( vecFunctions[ i ]->IsValid() && m_pFacade->GetTreeManager()->GetTypeManager()->IsTypeA( signature.GetTypeName(), vecFunctions[ i ]->GetContextType() ) >= 0 )
00120                                                 if ( vecFunctions[ i ]->GetName() == signature.GetName() && vecFunctions[ i ]->GetStereotype() == Ocl::Constraint::CS_METHODDEF && (int) vecFunctions[ i ]->GetFormalParameters().size() == signature.GetParameterCount() )
00121                                                         vecFeatures.push_back( new OclMeta::Method( signature.GetName(), CreateFormalParameters( vecFunctions[ i ]->GetFormalParameters() ), CreateReturnType( vecFunctions[ i ]->GetReturnType() ), new ConstraintMethod( m_pFacade->GetProject(), vecFunctions[ i ] ), true, true ) );
00122                                 }
00123                                 vecFunctions = m_pFacade->m_vecUserConstraintFunctions;
00124                                 for ( unsigned int i = 0 ; i < vecFunctions.size() ; i++ ) {
00125                                         if ( vecFunctions[ i ]->IsValid() && m_pFacade->GetTreeManager()->GetTypeManager()->IsTypeA( signature.GetTypeName(), vecFunctions[ i ]->GetContextType() ) >= 0 )
00126                                                 if ( vecFunctions[ i ]->GetName() == signature.GetName() && vecFunctions[ i ]->GetStereotype() == Ocl::Constraint::CS_ATTRIBUTEDEF )
00127                                                         vecFeatures.push_back( new OclMeta::Method( signature.GetName(), CreateFormalParameters( vecFunctions[ i ]->GetFormalParameters() ), CreateReturnType( vecFunctions[ i ]->GetReturnType() ), new ConstraintMethod( m_pFacade->GetProject(), vecFunctions[ i ] ), true, true ) );
00128                                 }
00129                         }
00130 
00131                 private :
00132                         TypeSeq CreateReturnType( const std::string& strType )
00133                         {
00134                                 TypeSeq vecType;
00135                                 OclCommon::Convert( strType, vecType );
00136                                 return vecType;
00137                         }
00138 
00139                         OclCommon::FormalParameterVector CreateFormalParameters( const OclCommon::FormalParameterVector& vecParamsIn ) const
00140                         {
00141                                 OclCommon::FormalParameterVector vecParams;
00142                                 for ( unsigned int j = 0 ; j < vecParamsIn.size() ; j++ ) {
00143                                         TypeSeq vecType;
00144                                         OclCommon::Convert( vecParamsIn[ j ].GetTypeName(), vecType );
00145                                         vecParams.push_back( OclCommon::FormalParameter( vecParamsIn[ j ].GetName(), vecType[ 0 ], true ) );
00146                                 }
00147                                 return vecParams;
00148                         }
00149         };
00150 
00151 //##############################################################################################################################################
00152 //
00153 //      C L A S S : OclGmeCM::Facade
00154 //
00155 //##############################################################################################################################################
00156 
00157         // Initialization Finalization
00158 
00159         Facade::Facade()
00160                 : m_spProject( NULL ), m_pTreeManager( NULL ), m_bViolationDlgExpanded( false )
00161         {
00162         }
00163 
00164         Facade::~Facade()
00165         {
00166                 Finalize();
00167                 if ( m_pTreeManager )
00168                         delete m_pTreeManager;
00169         }
00170 
00171         CComPtr<IMgaProject> Facade::GetProject() const
00172         {
00173                 return m_spProject;
00174         }
00175 
00176         CComPtr<IMgaMetaProject> Facade::GetMetaProject() const
00177         {
00178                 CComPtr<IMgaMetaProject> spMetaProject;
00179                 COMTHROW( m_spProject->get_RootMeta( &spMetaProject ) );
00180                 return spMetaProject;
00181         }
00182 
00183         OclTree::TreeManager* Facade::GetTreeManager() const
00184         {
00185                 return m_pTreeManager;
00186         }
00187 
00188         void Facade::Initialize( CComPtr<IMgaProject> spProject )
00189         {
00190                 if ( m_pTreeManager )
00191                         delete m_pTreeManager;
00192 
00193                 m_spProject = spProject;
00194 
00195                 m_bEnabled = true;
00196                 m_bEnabledEvents = true;
00197                 m_bEnabledInteractions = true;
00198 
00199                 // Create Important Objects
00200 
00201                 ConstraintDefinitionFactory* pCDFactory = new ConstraintDefinitionFactory();
00202                 pCDFactory->m_pFacade = this;
00203                 OclMeta::TypeManager* pTypeManager = new OclMeta::TypeManager( new TypeFactory( spProject ), new OclBasic::OperatorFactory(), new OclBasic::FunctionFactory(), pCDFactory );
00204 
00205                 m_pTreeManager = new OclTree::TreeManager( pTypeManager, new OclTree::ObjectNodeAdaptor(), new OclTree::CollectionNodeAdaptor() );
00206 
00207                 // Load Settings
00208 
00209                 CComPtr<IMgaFolder> spRootFolder;
00210                 COMTHROW( m_spProject->get_RootFolder( &spRootFolder ) );
00211                 CComPtr<IMgaRegNode> spSettings;
00212                 COMTHROW( spRootFolder->get_RegistryNode( CComBSTR( "ConstraintManagerSettings" ), &spSettings ) );
00213 
00214                 CComPtr<IMgaRegNode> spNode;
00215                 CString strTemp;
00216 
00217                 COMTHROW( spSettings->get_SubNodeByName( CComBSTR( "ShortCircuitLogicalOperators" ), &spNode ) );
00218                 COMTHROW( spNode->get_Value( PutOut( strTemp ) ) );
00219                 m_infoEvaluation.bEnabledSCLogical = strTemp.IsEmpty() || strTemp == "yes";
00220                 spNode = NULL;
00221                 strTemp.Empty();
00222 
00223                 COMTHROW( spSettings->get_SubNodeByName( CComBSTR( "ShortCircuitIterators" ), &spNode ) );
00224                 COMTHROW( spNode->get_Value( PutOut( strTemp ) ) );
00225                 m_infoEvaluation.bEnabledSCIterator = strTemp.IsEmpty() || strTemp == "yes";
00226                 spNode = NULL;
00227                 strTemp.Empty();
00228 
00229                 COMTHROW( spSettings->get_SubNodeByName( CComBSTR( "Tracking" ), &spNode ) );
00230                 COMTHROW( spNode->get_Value( PutOut( strTemp ) ) );
00231                 m_infoEvaluation.bEnabledTracking = strTemp.IsEmpty() || strTemp == "yes";
00232                 spNode = NULL;
00233                 strTemp.Empty();
00234 
00235                 COMTHROW( spSettings->get_SubNodeByName( CComBSTR( "ViolationCount" ), &spNode ) );
00236                 COMTHROW( spNode->get_Value( PutOut( strTemp ) ) );
00237                 if ( strTemp.IsEmpty() )
00238                         m_infoEvaluation.iViolationCount = -2;
00239                 else {
00240                         m_infoEvaluation.iViolationCount = _ttoi( strTemp );
00241                         if ( m_infoEvaluation.iViolationCount == 0 || m_infoEvaluation.iViolationCount < -2 || m_infoEvaluation.iViolationCount > 999 )
00242                                 m_infoEvaluation.iViolationCount = -2;
00243                 }
00244                 spNode = NULL;
00245                 strTemp.Empty();
00246 
00247                 COMTHROW( spSettings->get_SubNodeByName( CComBSTR( "ModelDepth" ), &spNode ) );
00248                 COMTHROW( spNode->get_Value( PutOut( strTemp ) ) );
00249                 if ( strTemp.IsEmpty() )
00250                         m_infoEvaluation.iModelDepth = 0; // 1; // terge
00251                 else {
00252                         m_infoEvaluation.iModelDepth = _ttoi( strTemp );
00253                         if ( m_infoEvaluation.iModelDepth < -1 || m_infoEvaluation.iModelDepth > 1 )
00254                                 m_infoEvaluation.iModelDepth = -1;
00255                 }
00256         }
00257 
00258         void Facade::Finalize()
00259         {
00260         }
00261 
00262         EvaluationInfo  Facade::GetEvaluationInfo() const
00263         {
00264                 return m_infoEvaluation;
00265         }
00266 
00267         void Facade::SetEvaluationInfo( const EvaluationInfo& info )
00268         {
00269                 m_infoEvaluation = info;
00270 
00271                 CComPtr<IMgaFolder> spRootFolder;
00272                 COMTHROW( m_spProject->get_RootFolder( &spRootFolder ) );
00273                 CComPtr<IMgaRegNode> spRootConstraints;
00274                 CString strTemp;
00275 
00276                 strTemp = ( info.bEnabledSCLogical ) ? "yes" : "no";
00277                 COMTHROW( spRootFolder->put_RegistryValue( CComBSTR( "ConstraintManagerSettings/ShortCircuitLogicalOperators" ), CComBSTR( strTemp ) ) );
00278 
00279                 strTemp = ( info.bEnabledSCIterator ) ? "yes" : "no";
00280                 COMTHROW( spRootFolder->put_RegistryValue( CComBSTR( "ConstraintManagerSettings/ShortCircuitIterators" ), CComBSTR( strTemp ) ) );
00281 
00282                 strTemp = ( info.bEnabledTracking ) ? "yes" : "no";
00283                 COMTHROW( spRootFolder->put_RegistryValue( CComBSTR( "ConstraintManagerSettings/Tracking" ), CComBSTR( strTemp ) ) );
00284 
00285                 strTemp.Empty(); strTemp.Format( _T("%d"), info.iViolationCount );
00286                 COMTHROW( spRootFolder->put_RegistryValue( CComBSTR( "ConstraintManagerSettings/ViolationCount" ), CComBSTR( strTemp ) ) );
00287 
00288                 strTemp.Empty(); strTemp.Format( _T("%d"), info.iModelDepth );
00289                 COMTHROW( spRootFolder->put_RegistryValue( CComBSTR( "ConstraintManagerSettings/ModelDepth" ), CComBSTR( strTemp ) ) );
00290         }
00291 
00292         void Facade::LoadMetaConstraintFunctions( OclGme::ConstraintFunctionVector& vecFaileds )
00293         {
00294                 // Load Meta Constraint Functions
00295 
00296                 OclGme::ConstraintFunctionVector vecFounds;
00297 
00298                 CComPtr<IMgaMetaFolder> spMetaFolder;
00299                 COMTHROW( GetMetaProject()->get_RootFolder( &spMetaFolder ) );
00300                 CComPtr<IMgaConstraints> spConstraints;
00301                 COMTHROW( spMetaFolder->get_Constraints( &spConstraints ) );
00302 
00303                 MGACOLL_ITERATE( IMgaConstraint, spConstraints ) {
00304                         CString strNmspc;
00305                         COMTHROW( MGACOLL_ITER->GetDefinedForNamespace( PutOut( strNmspc)));
00306                         constraint_type_enum eType;
00307                         COMTHROW( MGACOLL_ITER->get_Type( &eType ) );
00308                         if ( eType == CONSTRAINT_TYPE_FUNCTION ) {
00309                                 OclGme::SpConstraintFunction spConstraintFunction( new OclGme::ConstraintFunction( MGACOLL_ITER ) );
00310                                 spConstraintFunction->SetNamespace( std::string(CStringA(strNmspc)));
00311                                 spConstraintFunction->Register( m_pTreeManager );
00312                                 vecFounds.push_back( spConstraintFunction );
00313                         }
00314                 } MGACOLL_ITERATE_END;
00315 
00316                 LoadConstraintFunctions( vecFounds, vecFaileds, m_vecMetaConstraintFunctions );
00317                 m_vecMetaConstraintFunctions = vecFounds;
00318         }
00319 
00320         void Facade::LoadUserConstraintFunctions( OclGme::ConstraintFunctionVector& vecFaileds )
00321         {
00322                 // Load User Constraints
00323 
00324                 OclGme::ConstraintFunctionVector vecFounds;
00325 
00326                 LoadConstraintFunctions( vecFounds, vecFaileds, m_vecUserConstraintFunctions );
00327                 m_vecUserConstraintFunctions = vecFounds;
00328         }
00329 
00330         typedef std::vector< OclMeta::DependencySet > DependencySetVector;
00331 
00332         void Facade::LoadConstraintFunctions( OclGme::ConstraintFunctionVector& vecFounds, OclGme::ConstraintFunctionVector& vecFaileds, OclGme::ConstraintFunctionVector& vecSucceededs )
00333         {
00334                 // Parse, ParseContext
00335 
00336                 for ( unsigned int i = 0 ; i < vecFounds.size() ; i++ ) {
00337                         Ocl::Constraint::State eState = vecFounds[ i ]->Parse();
00338                         if ( eState == Ocl::Constraint::CS_PARSE_SUCCEEDED ) {
00339                                 vecFounds[ i ]->ParseContext();
00340                                 eState = vecFounds[ i ]->CheckContext();
00341                                 if ( eState == Ocl::Constraint::CS_CTX_CHECK_SUCCEEDED )
00342                                         vecSucceededs.push_back( vecFounds[ i ] );
00343                                 else
00344                                         vecFaileds.push_back( vecFounds[ i ] );
00345                         }
00346                         else
00347                                 vecFaileds.push_back( vecFounds[ i ] );
00348                 }
00349 
00350                 // Check All
00351 
00352                 OclGme::SpConstraintFunction spC;
00353                 for ( unsigned int i = 0 ; i < vecSucceededs.size() ; i ++ ) {
00354                         OclTree::TypeContextStack context;
00355                         context.AddVariable( "project", TypeSeq( 1, "gme::Project" ) );
00356                         spC = vecSucceededs[ i ];
00357                         if ( vecSucceededs[ i ]->Check( context ) != Ocl::Constraint::CS_CHECK_SUCCEEDED )
00358                                 vecFaileds.push_back( vecSucceededs[ i ] );
00359                 }
00360 
00361                 // Sort only succeeded so far
00362 
00363                 vecFounds = vecSucceededs;
00364                 vecSucceededs.clear();
00365                 DependencySetVector vecDependencySets;
00366 
00367                 for ( unsigned int i = 0 ; i < vecFounds.size() ; i ++ )
00368                         if ( vecFounds[ i ]->GetState() == Ocl::Constraint::CS_CHECK_SUCCEEDED ) {
00369                                 vecSucceededs.push_back( vecFounds[ i ] );
00370                                 vecDependencySets.push_back( vecFounds[ i ]->GetDependencySet() );
00371                         }
00372 
00373                 // Collect all Error Dependencies
00374 
00375                 StringVector vecErrors;
00376                 for ( unsigned int i = 0 ; i < vecFaileds.size() ; i++ ) {
00377                         std::string strSignature;
00378                         try {
00379                                 strSignature = GetSignature( vecFaileds[ i ] );
00380                         }
00381                         catch ( ... ) {
00382                                 strSignature = "#";
00383                         }
00384                         vecErrors.push_back( strSignature );
00385                 }
00386 
00387                 for (  unsigned int i = 0 ; i < vecErrors.size() ; i++ ) {
00388                         for ( unsigned int j = 0 ; j < vecDependencySets.size() ; j++ ) {
00389                                 OclMeta::DependencySet::iterator it = OclMeta::Dependency::LookUp( vecDependencySets[ j ], vecErrors[ i ] );
00390                                 if ( it != vecDependencySets[ j ].end() ) {
00391                                         OclMeta::Dependency::SetChecked( vecDependencySets[ j ], it, true );
00392                                         std::string strSignature = GetSignature( vecSucceededs[ j ] );
00393                                         if ( std::find( vecErrors.begin(), vecErrors.end(), strSignature ) == vecErrors.end() )
00394                                                 vecErrors.push_back( strSignature );
00395                                 }
00396                         }
00397                 }
00398 
00399                 // Set result dependencies
00400 
00401                 for ( unsigned int i = 0 ; i < vecSucceededs.size() ; i++ )
00402                         if ( vecSucceededs[ i ]->SetDependencyResult( vecDependencySets[ i ] ) == Ocl::Constraint::CS_CHECK_DEPENDENCY_FAILED )
00403                                 vecFaileds.push_back( vecSucceededs[ i ] );
00404 
00405                 // Sort only succeeded
00406 
00407                 vecFounds = vecSucceededs;
00408                 vecSucceededs.clear();
00409 
00410                 for ( unsigned int i = 0 ; i < vecFounds.size() ; i ++ )
00411                         if ( vecFounds[ i ]->GetState() == Ocl::Constraint::CS_CHECK_DEPENDENCY_SUCCEEDED )
00412                                 vecSucceededs.push_back( vecFounds[ i ] );
00413 
00414                 // Complete vecFounds
00415 
00416                 for ( unsigned int i = 0 ; i < vecFaileds.size() ; i ++ )
00417                         vecFounds.push_back( vecFaileds[ i ] );
00418         }
00419 
00420         std::string Facade::GetSignature( OclGme::SpConstraintFunction spCF )
00421         {
00422                 Ocl::Constraint::Stereotype eStereo = spCF->GetStereotype();
00423                 if ( eStereo == Ocl::Constraint::CS_ATTRIBUTEDEF ) {
00424                         OclSignature::Attribute signature( spCF->GetName(), spCF->GetContextType() );
00425                         return signature.Print();
00426                 }
00427                 else {
00428                         OclCommon::FormalParameterVector vecParameters = spCF->GetFormalParameters();
00429                         StringVector vecTypes;
00430                         for ( unsigned int i = 0 ; i < vecParameters.size() ; i++ ) {
00431                                 TypeSeq vecType;
00432                                 OclCommon::Convert( vecParameters[ i ].GetTypeName(), vecType );
00433                                 vecTypes.push_back( vecType[ 0 ] );
00434                         }
00435                         OclSignature::Method signature( spCF->GetName(), spCF->GetContextType(), vecTypes );
00436                         return signature.Print();
00437                 }
00438         }
00439 
00440         void Facade::LoadMetaConstraints( OclGme::ConstraintVector& vecFaileds )
00441         {
00442                 // Load Meta Constraints
00443 
00444                 OclCommonEx::MetaBaseVector vecMetas;
00445                 OclCommonEx::GetMetaObjects( GetMetaProject(), "", OBJTYPE_NULL, vecMetas );
00446 
00447                 OclGme::ConstraintVector vecFounds;
00448                 for ( unsigned int i = 0 ; i < vecMetas.size() ; i ++ ) {
00449                         std::string strName = "meta::" + OclCommonEx::GetObjectName( vecMetas[ i ].p );;
00450                         CComPtr<IMgaConstraints> spConstraints;
00451                         COMTHROW( vecMetas[ i ]->get_Constraints( &spConstraints ) );
00452                         MGACOLL_ITERATE( IMgaConstraint, spConstraints ) {
00453                                 CString strNmspc;
00454                                 COMTHROW( MGACOLL_ITER->GetDefinedForNamespace( PutOut( strNmspc)));
00455                                 constraint_type_enum eType;
00456                                 COMTHROW( MGACOLL_ITER->get_Type( &eType ) );
00457                                 if ( eType != CONSTRAINT_TYPE_FUNCTION ) {
00458                                         OclGme::SpConstraint spConstraint( new OclGme::Constraint( strName, MGACOLL_ITER ) );
00459                                         spConstraint->SetNamespace( std::string(CStringA(strNmspc)));
00460                                         spConstraint->Register( m_pTreeManager );
00461                                         vecFounds.push_back( spConstraint );
00462                                 }
00463                         } MGACOLL_ITERATE_END;
00464                 }
00465 
00466                 LoadConstraints( vecFounds, vecFaileds, m_vecMetaConstraints );
00467                 m_vecMetaConstraints = vecFounds;
00468         }
00469 
00470         void Facade::LoadUserConstraints( OclGme::ConstraintVector& vecFaileds )
00471         {
00472                 // Load User Constraints
00473 
00474                 OclGme::ConstraintVector vecFounds;
00475                 CComPtr<IMgaFolder> spRootFolder;
00476                 COMTHROW( m_spProject->get_RootFolder( &spRootFolder ) );
00477                 OclCommonEx::ObjectVector vecFolders;
00478                 OclCommonEx::GetKindFolders( spRootFolder, "", true, vecFolders );
00479                 for ( unsigned int i = 0 ; i < vecFolders.size() ; i++ ) {
00480                         CComQIPtr<IMgaFolder> spFolder = vecFolders[ i ].p;
00481                         StringVector vecLibraryPath = OclCommonEx::GetLibraryPath( spFolder.p );
00482                         CComPtr<IMgaRegNode> spRootConstraints;
00483                         COMTHROW( spFolder->get_RegistryNode( CComBSTR( "ConstraintDefinitions" ), &spRootConstraints ) );
00484                         CComPtr<IMgaRegNodes> spRegNodes;
00485                         COMTHROW( spRootConstraints->get_SubNodes( VARIANT_TRUE, &spRegNodes ) );
00486                         MGACOLL_ITERATE( IMgaRegNode, spRegNodes ) {
00487                                 OclGme::SpConstraint spConstraint( new OclGme::Constraint( MGACOLL_ITER, vecLibraryPath ) );
00488                                 spConstraint->Register( m_pTreeManager );
00489                                 vecFounds.push_back( spConstraint );
00490                         } MGACOLL_ITERATE_END;
00491                 }
00492 
00493                 LoadConstraints( vecFounds, vecFaileds, m_vecUserConstraints );
00494                 m_vecUserConstraints = vecFounds;
00495         }
00496 
00497         void Facade::LoadConstraints( OclGme::ConstraintVector& vecFounds, OclGme::ConstraintVector& vecFaileds, OclGme::ConstraintVector& vecSucceededs )
00498         {
00499                 for ( unsigned int i = 0 ; i < vecFounds.size() ; i++ ) {
00500                         Ocl::Constraint::State eState = vecFounds[ i ]->Parse();
00501                         if ( eState == Ocl::Constraint::CS_PARSE_SUCCEEDED ) {
00502                                 OclTree::TypeContextStack context;
00503                                 context.AddVariable( "project", TypeSeq( 1, "gme::Project" ) );
00504                                 eState = vecFounds[ i ]->Check( context );
00505                                 if ( eState == Ocl::Constraint::CS_CHECK_SUCCEEDED ) {
00506                                         eState = vecFounds[ i ]->SetDependencyResult( vecFounds[ i ]->GetDependencySet() );
00507                                         if ( eState == Ocl::Constraint::CS_CHECK_DEPENDENCY_SUCCEEDED )
00508                                                 vecSucceededs.push_back( vecFounds[ i ] );
00509                                         else
00510                                                 vecFaileds.push_back( vecFounds[ i ] );
00511                                 }
00512                                 else
00513                                         vecFaileds.push_back( vecFounds[ i ] );
00514                         }
00515                         else
00516                                 vecFaileds.push_back( vecFounds[ i ] );
00517                 }
00518         }
00519 
00520         void Facade::GetObjectConstraints( CComPtr<IMgaObject> spObject, EvaluationRecordVector& vecInputs, unsigned long ulCurrentEventMask )
00521         {
00522                 std::string strKind = "meta::" + OclCommonEx::GetObjectKind( spObject );
00523 
00524                 // Collect Meta Constraints
00525 
00526                 for ( unsigned int i = 0 ; i < m_vecMetaConstraints.size() ; i++ ) {
00527                         if ( m_vecMetaConstraints[ i ]->IsValid() ) {
00528                                 CString sK = OclCommonEx::Convert( strKind );
00529                                 CString cT = OclCommonEx::Convert( m_vecMetaConstraints[ i ]->GetContextType()  );
00530                                 if ( strKind == m_vecMetaConstraints[ i ]->GetContextType() ) {
00531                                         OclGme::Constraint::EnableInfo eInfo = m_vecMetaConstraints[ i ]->GetEnableInfo( spObject );
00532                                         if ( eInfo > OclGme::Constraint::CE_NONE && eInfo <= OclGme::Constraint::CE_ENABLED_READONLY ) {
00533                                                 if ( ulCurrentEventMask == 0x0 || ( m_vecMetaConstraints[ i ]->GetEventMask() & ulCurrentEventMask ) ) {
00534                                                         EvaluationRecord input;
00535                                                         input.spObject = CREATE_GMEOBJECT( m_pTreeManager->GetTypeManager(), spObject );
00536                                                         input.spConstraint = m_vecMetaConstraints[ i ];
00537                                                         vecInputs.push_back( input );
00538                                                 }
00539                                         }
00540                                 }
00541                         }
00542                 }
00543 
00544                 // Collect User Constraints
00545 
00546                 for ( unsigned int i = 0 ; i < m_vecUserConstraints.size() ; i++ ) {
00547                         if ( m_vecUserConstraints[ i ]->IsValid() ) {
00548                                 if ( strKind == m_vecUserConstraints[ i ]->GetContextType() ) {
00549                                         OclGme::Constraint::EnableInfo eInfo = m_vecUserConstraints[ i ]->GetEnableInfo( spObject );
00550                                         if ( eInfo > OclGme::Constraint::CE_NONE && eInfo <= OclGme::Constraint::CE_ENABLED_READONLY ) {
00551                                                 if ( ulCurrentEventMask == 0x0 || ( m_vecUserConstraints[ i ]->GetEventMask() & ulCurrentEventMask ) ) {
00552                                                         EvaluationRecord input;
00553                                                         input.spObject = CREATE_GMEOBJECT( m_pTreeManager->GetTypeManager(), spObject );
00554                                                         input.spConstraint = m_vecUserConstraints[ i ];
00555                                                         vecInputs.push_back( input );
00556                                                 }
00557                                         }
00558                                 }
00559                         }
00560                 }
00561         }
00562 
00563         void Facade::SortByPriority( EvaluationRecordVector& vecInputs ) const
00564         {
00565                 EvaluationRecordVector vecInputs2 = vecInputs;
00566                 vecInputs.clear();
00567 
00568                 for ( unsigned int i = 0 ; i < vecInputs2.size() ; i++ ) {
00569                         bool bWasAdded = false;
00570                         for ( EvaluationRecordVector::iterator it = vecInputs.begin() ; it != vecInputs.end() ; ++it ) {
00571                                 if( vecInputs2[ i ].spConstraint->GetPriority() <= (*it).spConstraint->GetPriority() ) {
00572                                         vecInputs.insert( it, vecInputs2[ i ] );
00573                                         bWasAdded = true;
00574                                         break;
00575                                 }
00576                         }
00577                         if ( ! bWasAdded )
00578                                 vecInputs.push_back( vecInputs2[ i ] );
00579                 }
00580                 int num = vecInputs.size();
00581                 for ( int ii = 0 ; num  &&  ii < num-1 ; ii++ ) 
00582                 {
00583                         TRACE("item: %d, p1: %d, p2: %d \n", ii, vecInputs[ii].spConstraint->GetPriority(), vecInputs[ii+1].spConstraint->GetPriority());
00584                         ASSERT(vecInputs[ii].spConstraint->GetPriority() <= vecInputs[ii+1].spConstraint->GetPriority());
00585                 }
00586         }
00587 
00588         bool Facade::getConstraintFunctionText(std::string &name, std::string &text)
00589         {
00590                                 text = "";
00591                                 for (unsigned int i = 0 ; i < m_vecUserConstraintFunctions.size() ; i++ ) 
00592                                 {
00593                                         bool valid = m_vecUserConstraintFunctions[ i ]->IsValid();
00594                                         std::string fname = m_vecUserConstraintFunctions[ i ]->GetName();// GetFullName();
00595                                         if ( valid  &&  fname == name)
00596                                         {
00597                                                 text = m_vecUserConstraintFunctions[ i ]->GetText();
00598                                                 return true;
00599                                         }
00600                                 }
00601                                 for ( unsigned int i = 0 ; i < m_vecMetaConstraintFunctions.size() ; i++ ) 
00602                                 {
00603                                         bool valid = m_vecMetaConstraintFunctions[ i ]->IsValid();
00604                                         std::string fname = m_vecMetaConstraintFunctions[ i ]->GetName();// GetFullName();
00605                                         if ( valid  &&  fname == name)
00606                                         {
00607                                                 text = m_vecMetaConstraintFunctions[ i ]->GetText();
00608                                                 return true;
00609                                         }
00610                                 }
00611                                 return false;
00612         }
00613 
00614         void Facade::addFunctionTexts(EvaluationRecord &rec)
00615         {
00616                 int vnum = rec.vecViolations.size();
00617                 int serial = 1;
00618                 for (int k=0; k< vnum; k++)
00619                 {
00620                         std::string name = rec.vecViolations[k].methodName;
00621                         if (!rec.vecViolations[k].methodName.empty())
00622                         {
00623                                 FuncDesc::iterator it = rec.calledFunctions.find(name);
00624                                 if (it != rec.calledFunctions.end())
00625                                         continue;
00626                                 std::string text;
00627                                 if (getConstraintFunctionText(name, text))
00628                                 {
00629                                         FuncItem item;
00630                                         item.text = text;
00631                                         item.serial = serial;
00632                                         std::pair<FuncDesc::iterator, bool> pp = rec.calledFunctions.insert(FuncDesc::value_type(name, item));
00633                                         ASSERT(pp.second);
00634                                         if (pp.second)
00635                                                 serial++;
00636                                 }
00637                                 else
00638                                         ASSERT(0);
00639                         }
00640                 }
00641         }
00642 
00643         void Facade::updateLineno(EvaluationRecord &rec)
00644         {
00645                 int recsize = rec.vecViolations.size();
00646                 for (int i=0; i < recsize; i++)
00647                 {
00648                         if (!rec.vecViolations[i].methodName.empty())
00649                         {
00650                                 std::string name = rec.vecViolations[i].methodName;
00651                                 FuncDesc::iterator it = rec.calledFunctions.find(name);
00652                                 if (it != rec.calledFunctions.end())
00653                                         rec.vecViolations[i].position.iLine += it->second.serial*1000;
00654                                 else
00655                                         ASSERT(0);;
00656                         }
00657                 }
00658         }
00659 
00660         HRESULT Facade::EvaluateConstraints( EvaluationRecordVector& vecInputs, bool bShowProgress, IUnknown **punk )
00661         {
00662                 // Initialization
00663 
00664                 SortByPriority( vecInputs );
00665 
00666                 CSmallMessageBox dlgProgress;
00667                 if ( bShowProgress )
00668                         dlgProgress.DoModeless( vecInputs.size() );
00669 
00670                 CViolationDialog dlgErrors( m_bViolationDlgExpanded, NULL, m_spProject );
00671 
00672                 int iViolationCount= 0;
00673                 bool bWasCritical = false;
00674                 bool bStopEvaluation = false;
00675                 long lPriority = 1;
00676                 bool closeNotRequested = true;
00677 
00678                 int loopcount = vecInputs.size();
00679                 for ( int i = 0 ; i < loopcount && ! bStopEvaluation ; i++ ) {
00680 
00681                         OclGme::SpConstraint constraint = vecInputs[ i ].spConstraint;
00682 //                      vecInputs[ i ].vecViolations.clear();
00683                         // Level condition for terminating the evaluation
00684 
00685                         if ( m_infoEvaluation.iViolationCount == -1 && vecInputs[ i ].spConstraint->GetPriority() > lPriority && iViolationCount > 0 )
00686                                 break;
00687 
00688                         // Evaluate
00689 
00690                         CComPtr<IMgaObject> spObject;
00691                         (( OclGmeCM::Object*) vecInputs[ i ].spObject.GetImplementation() )->GetValue( spObject );
00692                         OclTree::ObjectContextStack context;
00693                         context.AddVariable( "project", CREATE_GMEPROJECT( m_pTreeManager->GetTypeManager(), m_spProject ) );
00694                         context.AddVariable( "self", vecInputs[ i ].spObject );
00695                         vecInputs[ i ].spObject = vecInputs[ i ].spConstraint->Evaluate( context, m_infoEvaluation.bEnabledSCLogical, m_infoEvaluation.bEnabledSCIterator, m_infoEvaluation.bEnabledTracking );
00696                         vecInputs[ i ].vecViolations = vecInputs[ i ].spConstraint->GetViolations();
00697                         vecInputs[ i ].spConstraint->ClearViolations();
00698 
00699                         // Refresh Progress
00700 
00701                         if ( bShowProgress ) {
00702                                 closeNotRequested = dlgProgress.IncrementProgress();
00703                                 if ( !closeNotRequested )
00704                                         bStopEvaluation = true;
00705                         }
00706 
00707                         // Check the result
00708 
00709                         bool bWasViolation = false;
00710                         if ( vecInputs[ i ].spObject.IsUndefined() )
00711                                 bWasViolation = true;
00712                         else {
00713                                 DECL_BOOLEAN( bResult, vecInputs[ i ].spObject );
00714                                 if ( ! bResult )
00715                                         bWasViolation = true;
00716                         }
00717 
00718                         // Terminate the evaluation if necessary
00719 
00720                         if ( bWasViolation ) {
00721                                 if ( bShowProgress && m_infoEvaluation.iViolationCount == iViolationCount + 1 )
00722                                         bStopEvaluation = true;
00723                                 iViolationCount++;
00724                                 addFunctionTexts(vecInputs[ i ]);
00725                                 updateLineno(vecInputs[ i ]);
00726                                 dlgErrors.AddItem( vecInputs[ i ] );
00727                                 if ( ! bShowProgress && vecInputs[ i ].spConstraint->GetPriority() == 1 )
00728                                         bWasCritical = true;
00729                         }
00730                         lPriority = vecInputs[ i ].spConstraint->GetPriority();
00731 //                      vecInputs[ i ].vecViolations.clear();
00732                 }
00733 
00734                 // Finalization
00735 
00736                 if ( bShowProgress )
00737                         dlgProgress.UndoModeless();
00738 
00739                 // Show Errors
00740 
00741                 if ( iViolationCount > 0 ) {
00742 
00743                         if ( bShowProgress )
00744                                 dlgErrors.EnableOK();
00745                         else {
00746                                 if ( ! bWasCritical )
00747                                         dlgErrors.EnableOK();
00748                                 dlgErrors.EnableAbort();
00749                         }
00750 
00751                         int iResult = dlgErrors.DoModal();
00752                         m_bViolationDlgExpanded = dlgErrors.IsExpanded();
00753                         if (punk)
00754                                 dlgErrors.GetGotoPunk(punk);
00755                         if ( iResult != IDOK ) {
00756                                 SetErrorInfo(L"Constraint violation");
00757                                 return E_MGA_CONSTRAINT_VIOLATION;
00758                         } else
00759                                 S_OK;
00760                 }
00761                 else
00762                         if ( bShowProgress && closeNotRequested )
00763                                 CSmallMessageBox().DoModal();
00764                 return S_OK;
00765         }
00766 
00767         void Facade::CollectConstraints( CComPtr<IMgaObject> spObject, bool bRecursive, EvaluationRecordVector& vecInputs )
00768         {
00769                 GetObjectConstraints( spObject, vecInputs, 0x0 );
00770 
00771                 if ( bRecursive ) {
00772                         CComPtr<IMgaFCOs> spFCOs;
00773                         CComQIPtr<IMgaFolder> spFolder = spObject;
00774                         if ( spFolder.p ) {
00775                                 CComPtr<IMgaFolders> spFolders;
00776                                 COMTHROW( spFolder->get_ChildFolders( &spFolders ) );
00777                                 MGACOLL_ITERATE( IMgaFolder, spFolders ) {
00778                                         CollectConstraints( MGACOLL_ITER.p, true, vecInputs );
00779                                 } MGACOLL_ITERATE_END;
00780                                 COMTHROW( spFolder->get_ChildFCOs( &spFCOs ) );
00781                         }
00782                         else {
00783                                 CComQIPtr<IMgaModel> spModel = spObject;
00784                                 if ( spModel.p )
00785                                         COMTHROW( spModel->get_ChildFCOs( &spFCOs ) );
00786                         }
00787 
00788                         if ( spFCOs.p ) {
00789                                 MGACOLL_ITERATE( IMgaFCO, spFCOs ) {
00790                                         CollectConstraints( MGACOLL_ITER.p, true, vecInputs );
00791                                 } MGACOLL_ITERATE_END;
00792                         }
00793                 }
00794         }
00795 
00796         void Facade::CollectConstraints( CComPtr<IMgaObject> spObject, unsigned long ulCurrentEventMask, int iCheckedLevels, EvaluationRecordVector& vecInputs )
00797         {
00798                 CComPtr<IMgaObject> spParent;
00799                 COMTHROW( spObject->GetParent( &spParent ) );
00800 
00801                 if ( spParent.p ) {
00802                         EvaluationRecordVector vecInnerInputs;
00803                         GetObjectConstraints( spParent, vecInnerInputs, ulCurrentEventMask );
00804 
00805                         for ( unsigned int i = 0 ; i < vecInnerInputs.size() ; i++ ) {
00806                                 switch( vecInnerInputs[ i ].spConstraint->GetDepth() ) {
00807                                         case CONSTRAINT_DEPTH_ZERO :
00808                                                 break;
00809                                         case CONSTRAINT_DEPTH_ONE :
00810                                                 if ( iCheckedLevels >= 1 )
00811                                                         break;
00812                                         default :
00813                                                 vecInputs.push_back( vecInnerInputs[ i ] );
00814                                 }
00815                         }
00816 
00817                         CollectConstraints( spParent, ulCurrentEventMask, iCheckedLevels + 1, vecInputs );
00818                 }
00819         }
00820 
00821         void Facade::CollectConstraints( CComPtr<IMgaObject> spObject, EvaluationRecordVector& vecInputs )
00822         {
00823                 CollectConstraints( spObject, m_infoEvaluation.iModelDepth == -1, vecInputs );
00824                 if ( m_infoEvaluation.iModelDepth == 1 ) {
00825                         CComQIPtr<IMgaModel> spModel = spObject;
00826                         if ( spModel.p ) {
00827                                 CComPtr<IMgaFCOs> spFCOs;
00828                                 COMTHROW( spModel->get_ChildFCOs( &spFCOs ) );
00829                                 MGACOLL_ITERATE( IMgaFCO, spFCOs ) {
00830                                         CollectConstraints( MGACOLL_ITER.p, false, vecInputs );
00831                                 } MGACOLL_ITERATE_END;
00832                         }
00833                 }
00834         }
00835 
00836         HRESULT Facade::EvaluateAll(IUnknown **punk)
00837         {
00838                 AfxGetApp()->DoWaitCursor( 1 );
00839                 EvaluationRecordVector vecInputs;
00840                 CComPtr<IMgaFolder> spRootFolder;
00841                 COMTHROW( m_spProject->get_RootFolder( &spRootFolder ) );
00842                 CollectConstraints( spRootFolder.p, true, vecInputs );
00843                 AfxGetApp()->DoWaitCursor( -1 );
00844                 return EvaluateConstraints( vecInputs, true, punk );
00845         }
00846 
00847         HRESULT Facade::Evaluate( CComPtr<IMgaObject> spObject, IUnknown **punk )
00848         {
00849                 AfxGetApp()->DoWaitCursor( 1 );
00850                 EvaluationRecordVector vecInputs;
00851                 CollectConstraints( spObject, vecInputs );
00852                 AfxGetApp()->DoWaitCursor( -1 );
00853                 return EvaluateConstraints( vecInputs, true, punk );
00854         }
00855 
00856         HRESULT Facade::Evaluate( const OclCommonEx::ObjectVector& vecObjects, IUnknown **punk)
00857         {
00858                 AfxGetApp()->DoWaitCursor( 1 );
00859                 EvaluationRecordVector vecInputs;
00860                 for ( unsigned int i = 0 ; i < vecObjects.size() ; i++ )
00861                         CollectConstraints( vecObjects[ i ].p, vecInputs );
00862                 AfxGetApp()->DoWaitCursor( -1 );
00863                 return EvaluateConstraints( vecInputs, true, punk );
00864         }
00865 
00866         HRESULT Facade::Evaluate( CComPtr<IMgaObject> spObject, unsigned long ulCurrentEventMask)
00867         {
00868                 AfxGetApp()->DoWaitCursor( 1 );
00869                 EvaluationRecordVector vecInputs;
00870                 GetObjectConstraints( spObject, vecInputs, ulCurrentEventMask );
00871 
00872                 if ( ! ( ulCurrentEventMask & OBJEVENT_DESTROYED ) )
00873                         CollectConstraints( spObject, ulCurrentEventMask, 0, vecInputs );
00874                 AfxGetApp()->DoWaitCursor( -1 );
00875                 return EvaluateConstraints( vecInputs, false, NULL);
00876         }
00877 
00878 }; // namespace OclGmeCM