GME  13
OclConstraint.cpp
Go to the documentation of this file.
00001 //###############################################################################################################################################
00002 //
00003 //      Object Constraint Language Generic Manager
00004 //      OCLConstraint.h
00005 //
00006 //###############################################################################################################################################
00007 #include "StdAfx.h"
00008 #include "Solve4786.h"
00009 #include "OCLConstraint.h"
00010 
00011 #include "OCLObjectExBasic.h"
00012 #include "OCLTokens.h"
00013 #include "OCLParser.h"
00014 
00015 //udmoclpat_oclconstraint_cpp_1 __please do not remove or change this line__
00016 
00017 namespace Ocl
00018 {
00019         Constraint::Stereotype StringToStereotype( const std::string& str )
00020         {
00021                 if ( str == "inv" )
00022                         return Constraint::CS_INVARIANT;
00023                 if ( str == "pre" )
00024                         return Constraint::CS_PRECONDITION;
00025                 if ( str == "post" )
00026                         return Constraint::CS_POSTCONDITION;
00027                 if ( str == "defattribute" )
00028                         return Constraint::CS_ATTRIBUTEDEF;
00029                 return Constraint::CS_METHODDEF;
00030         }
00031 
00032 //##############################################################################################################################################
00033 //
00034 //      C L A S S : Ocl::Constraint
00035 //
00036 //##############################################################################################################################################
00037 
00038         Constraint::Constraint()
00039                 :  m_pManager( NULL ), m_pCtxConstraint( NULL ), m_pConstraint( NULL ), m_strName( "" ), m_strText( "" ), m_eState( CS_UNREGISTERED ), m_bContextSucceeded( false )
00040         {
00041         }
00042 
00043         Constraint::Constraint( OclTree::TreeManager* pManager )
00044                 : m_pManager( pManager ), m_pCtxConstraint( NULL ), m_pConstraint( NULL ), m_strName( "" ), m_strText( "" ), m_eState( CS_UNREGISTERED ), m_bContextSucceeded( false )
00045         {
00046                 if ( pManager )
00047                         m_eState = CS_REGISTERED;
00048         }
00049 
00050         Constraint::Constraint( OclTree::TreeManager* pManager, const std::string& strName, const std::string& strText, bool bDynamic )
00051                 : m_pManager( pManager ), m_pCtxConstraint( NULL ), m_pConstraint( NULL ), m_strText( strText ), m_strName( strName ), m_eState( CS_UNREGISTERED ), m_bDynamic( bDynamic ), m_bContextSucceeded( false )
00052         {
00053                 if ( pManager ) {
00054                         m_eState = CS_REGISTERED;
00055                         if ( ! m_strName.empty() && ! m_strText.empty() )
00056                                 m_eState = CS_DEFINED;
00057                 }
00058         }
00059 
00060         Constraint::~Constraint()
00061         {
00062                 if ( m_pCtxConstraint )
00063                         delete m_pCtxConstraint;
00064                 if ( m_pConstraint )
00065                         delete m_pConstraint;
00066         }
00067 
00068         Constraint::State Constraint::Register( OclTree::TreeManager* pManager )
00069         {
00070                 if ( pManager && m_eState == CS_UNREGISTERED ) {
00071                         m_eState = ( ! m_strName.empty() && ! m_strText.empty() ) ? CS_DEFINED : CS_REGISTERED;
00072                         m_pManager = pManager;
00073                 }
00074                 return m_eState;
00075         }
00076 
00077         Constraint::State Constraint::Define( const std::string& strName, const std::string& strText, bool bDynamic )
00078         {
00079                 if ( ! strName.empty() || ! strText.empty() && m_eState <= CS_DEFINED ) {
00080                         m_bDynamic = bDynamic;
00081                         if ( ! strName.empty() )
00082                                 m_strName = strName;
00083                         if ( ! strText.empty() )
00084                                 m_strText = strText;
00085                         if ( m_eState == CS_REGISTERED && ! m_strName.empty() && ! m_strText.empty() )
00086                                 m_eState = CS_DEFINED;
00087                 }
00088                 return m_eState;
00089         }
00090 
00091         std::string Constraint::GetDefinedName() const
00092         {
00093                 return m_strName;
00094         }
00095 
00096         Constraint::State Constraint::GetState() const
00097         {
00098                 return m_eState;
00099         }
00100 
00101         bool Constraint::IsValid() const
00102         {
00103                 return ! ( m_eState == CS_CTX_PARSE_FAILED || m_eState == CS_CTX_CHECK_FAILED || m_eState == CS_PARSE_FAILED || m_eState == CS_CHECK_FAILED || m_eState == CS_CHECK_DEPENDENCY_FAILED );
00104         }
00105 
00106         bool Constraint::IsDefined() const
00107         {
00108                 return m_eState >= CS_DEFINED;
00109         }
00110 
00111         std::string Constraint::GetText() const
00112         {
00113                 return m_strText;
00114         }
00115 
00116         bool Constraint::IsDynamic() const
00117         {
00118                 return m_bDynamic;
00119         }
00120 
00121         Constraint::State Constraint::ParseContext()
00122         {
00123                 if ( m_eState < CS_DEFINED )
00124                         throw m_eState;
00125                 if ( m_pCtxConstraint )
00126                         return CS_CTX_PARSE_SUCCEEDED;
00127                 m_pCtxConstraint = OCLParser::ParseConstraint( m_pManager, m_strText, true, m_poolCtxExceptions );
00128                 if ( m_poolCtxExceptions.IsEmpty() && m_pCtxConstraint ) {
00129                         if ( ! m_pConstraint )
00130                                 m_eState = CS_CTX_PARSE_SUCCEEDED;
00131                         return CS_CTX_PARSE_SUCCEEDED;
00132                 }
00133                 if ( m_pCtxConstraint ) {
00134                         delete m_pCtxConstraint;
00135                         m_pCtxConstraint = NULL;
00136                 }
00137                 return m_eState = CS_CTX_PARSE_FAILED;
00138         }
00139 
00140         std::string Constraint::GetName() const
00141         {
00142                 if ( m_pCtxConstraint )
00143                         return m_pCtxConstraint->m_strName;
00144                 if ( m_pConstraint )
00145                         return m_pConstraint->m_strName;
00146                 throw m_eState;
00147         }
00148 
00149         Constraint::Stereotype Constraint::GetStereotype() const
00150         {
00151                 if ( m_pCtxConstraint )
00152                         return StringToStereotype( m_pCtxConstraint->m_pContext->m_strStereotype );
00153                 if ( m_pConstraint )
00154                         return StringToStereotype( m_pConstraint->m_pContext->m_strStereotype );
00155                 throw m_eState;
00156         }
00157 
00158         Constraint::State Constraint::CheckContext()
00159         {
00160                 if ( m_eState == CS_CTX_CHECK_FAILED )
00161                         return m_eState;
00162                 if ( m_bContextSucceeded || m_eState > CS_CHECK_SUCCEEDED || m_eState == CS_CTX_CHECK_SUCCEEDED )
00163                         return CS_CTX_CHECK_SUCCEEDED;
00164                 if ( ! m_pCtxConstraint )
00165                         throw CS_CTX_CHECK_FAILED;
00166                 OclTree::TypeContext context( m_nmsp);
00167                 m_bContextSucceeded = m_pCtxConstraint->Check( context );
00168                 m_poolCtxExceptions = context.m_poolExceptions;
00169                 Constraint::State eState = ( m_bContextSucceeded ) ? CS_CTX_CHECK_SUCCEEDED : CS_CTX_CHECK_FAILED;
00170                 if ( m_eState == CS_CTX_PARSE_SUCCEEDED )
00171                         m_eState = eState;
00172                 return eState;
00173         }
00174 
00175         std::string Constraint::GetContextType() const
00176         {
00177                 if ( m_bContextSucceeded )
00178                         return m_pCtxConstraint->m_pContext->m_strType;
00179                 if ( m_eState >= CS_CHECK_SUCCEEDED )
00180                         return m_pConstraint->m_pContext->m_strType;
00181                 throw m_eState;
00182         }
00183 
00184         std::string Constraint::GetFullName() const
00185         {
00186                 return GetContextType() + "::" + GetName();
00187         }
00188 
00189         std::string Constraint::GetNamespace() const
00190         {
00191                 return m_nmsp;
00192         }
00193 
00194         void Constraint::SetNamespace( const std::string& nm)
00195         {
00196                 m_nmsp = nm;
00197         }
00198 
00199 
00200         std::string Constraint::GetReturnType() const
00201         {
00202                 if ( m_bContextSucceeded || m_eState >= CS_CHECK_SUCCEEDED ) {
00203                         if ( GetStereotype() == CS_INVARIANT )
00204                                 throw CS_INVARIANT;
00205                         if ( m_bContextSucceeded )
00206                                 return m_pCtxConstraint->m_pContext->m_strReturnType;
00207                         return m_pConstraint->m_pContext->m_strReturnType;
00208                 }
00209                 throw m_eState;
00210         }
00211 
00212         OclCommon::FormalParameterVector Constraint::GetFormalParameters() const
00213         {
00214                 if ( m_bContextSucceeded || m_eState >= CS_CHECK_SUCCEEDED ) {
00215                         if ( GetStereotype() == CS_INVARIANT )
00216                                 throw CS_INVARIANT;
00217                         if ( m_bContextSucceeded )
00218                                 return m_pCtxConstraint->m_pContext->m_vecParameters;
00219                         return m_pConstraint->m_pContext->m_vecParameters;
00220                 }
00221                 throw m_eState;
00222         }
00223 
00224         Constraint::State Constraint::Parse()
00225         {
00226                 if ( m_eState < CS_DEFINED )
00227                         throw m_eState;
00228                 if ( m_eState == CS_PARSE_FAILED )
00229                         return m_eState;
00230                 if ( m_eState >= CS_PARSE_SUCCEEDED )
00231                         return CS_PARSE_SUCCEEDED;
00232                 m_pConstraint = OCLParser::ParseConstraint( m_pManager, m_strText, false, m_poolExceptions );
00233                 if ( m_poolExceptions.IsEmpty() && m_pConstraint )
00234                         return m_eState = CS_PARSE_SUCCEEDED;
00235                 if ( m_pConstraint ) {
00236                         delete m_pConstraint;
00237                         m_pConstraint = NULL;
00238                 }
00239                 return m_eState = CS_PARSE_FAILED;
00240         }
00241 
00242         Constraint::State Constraint::Check( OclTree::TypeContextStack& ctxTypes )
00243         {
00244                 if ( m_eState < CS_PARSE_SUCCEEDED )
00245                         throw m_eState;
00246                 if ( m_eState == CS_CHECK_FAILED )
00247                         return m_eState;
00248                 if ( m_eState >= CS_CHECK_SUCCEEDED )
00249                         return CS_CHECK_SUCCEEDED;
00250                 OclTree::TypeContext context( m_nmsp);
00251                 context.m_ctxTypes = ctxTypes;
00252                 bool bResult = m_pConstraint->Check( context );
00253                 m_poolExceptions = context.m_poolExceptions;
00254                 return m_eState = ( bResult ) ? CS_CHECK_SUCCEEDED : CS_CHECK_FAILED;
00255         }
00256 
00257         OclMeta::DependencySet Constraint::GetDependencySet() const
00258         {
00259                 if ( m_eState < CS_CHECK_SUCCEEDED )
00260                         throw m_eState;
00261                 return m_pConstraint->m_pContext->m_setDependencies;
00262         }
00263 
00264         Constraint::State Constraint::SetDependencyResult( const OclMeta::DependencySet& setDependencies )
00265         {
00266                 if ( m_eState != CS_CHECK_SUCCEEDED )
00267                         throw m_eState;
00268                 bool bWasError = false;
00269                 for ( OclMeta::DependencySet::const_iterator i = setDependencies.begin() ; i != setDependencies.end() ; ++i ) {
00270                         if ( (*i).m_bFailed ) {
00271                                 bWasError = true;
00272                                 OclCommon::Exception exp( OclCommon::Exception( OclCommon::Exception::ET_SEMANTIC, EX_CONSTRAINT_DEF_FAILED, (*i).m_strSignature, (*i).m_position.iLine, (*i).m_position.iColumn ) );
00273                                 m_poolExceptions.Add( exp );
00274                         }
00275                 }
00276                 return m_eState = ( bWasError ) ? CS_CHECK_DEPENDENCY_FAILED : CS_CHECK_DEPENDENCY_SUCCEEDED;
00277         }
00278 
00279         std::string Constraint::Print() const
00280         {
00281                 if ( m_eState >= CS_CHECK_SUCCEEDED )
00282                         return m_pConstraint->Print( "" );
00283                 throw m_eState;
00284         }
00285 
00286         std::string Constraint::PrintTree() const
00287         {
00288                 if ( m_eState >= CS_PARSE_SUCCEEDED )
00289                         return m_pConstraint->Print( "" );
00290                 throw m_eState;
00291         }
00292 
00293         OclMeta::Object Constraint::Evaluate( OclTree::ObjectContextStack& ctxObjects, bool bEnableLogicalShortCircuit, bool bEnableIteratorShortCircuit, bool bEnableTracking )
00294         {
00295                 if ( m_eState < CS_CHECK_DEPENDENCY_SUCCEEDED )
00296                         throw m_eState;
00297                 OclTree::ObjectContext context;
00298                 context.oCtx = ctxObjects;
00299                 context.bDoSnapshot = true;
00300                 context.iViolationCount = 0;
00301                 context.m_bHasException = false;
00302                 context.m_bShortCircuitLogical = bEnableLogicalShortCircuit;
00303                 context.m_bShortCircuitIterator = bEnableIteratorShortCircuit;
00304                 context.m_bEnableTracking = bEnableTracking;
00305 
00306                 OclMeta::Object spResult = m_pConstraint->Evaluate( context );
00307                 m_vecViolations = context.vecViolations;
00308                 if ( spResult.IsUndefined() )
00309                         m_eState = CS_EVAL_FAILED;
00310                 else
00311                         m_eState = CS_EVAL_SUCCEEDED;
00312                 return spResult;
00313         }
00314 
00315         OclCommon::ExceptionPool Constraint::GetExceptions()
00316         {
00317                 if ( m_eState <= CS_DEFINED )
00318                         throw m_eState;
00319                 return ( m_eState > CS_CTX_PARSE_FAILED && m_eState <= CS_CTX_CHECK_SUCCEEDED ) ? m_poolCtxExceptions : m_poolExceptions;
00320         }
00321 
00322         OclCommon::ExceptionPool Constraint::GetExceptions( bool bContext )
00323         {
00324                 if ( m_eState <= CS_DEFINED )
00325                         throw m_eState;
00326                 return ( bContext ) ? m_poolCtxExceptions : m_poolExceptions;
00327         }
00328 
00329         // this method called once at the end not for each constarint function ?? !!
00330         // m_vecViolations will lose for the constarint functions
00331         OclTree::ViolationVector Constraint::GetViolations()
00332         {
00333                 if ( m_eState < CS_EVAL_FAILED )
00334                         throw m_eState;
00335                 return m_vecViolations;
00336         }
00337 
00338         void Constraint::ClearViolations()
00339         {
00340                 int db = m_vecViolations.size();
00341                 m_vecViolations.clear();;
00342                 db = m_vecViolations.size();
00343         }
00344 
00345 //udmoclpat_oclconstraint_cpp_2 __please do not remove or change this line__
00346 
00347 }; // namespace Ocl