00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #pragma warning ( disable : 4503 )
00023
00024 #include "stdafx.h"
00025
00026 #include "BONImpl.h"
00027 #include "Extensions.h"
00028
00029
00030 #ifndef NAMESPACE_PREF
00031 #define NAMESPACE_PREF ""
00032 #endif
00033
00034 namespace BON
00035 {
00036 void splitKinds( const std::string& strKinds, std::vector<std::string>& vecKinds )
00037 {
00038 CStringA str( strKinds.c_str() );
00039 str.TrimLeft();
00040 str.TrimRight();
00041 if ( str.IsEmpty() )
00042 vecKinds.push_back( "gme::Object" );
00043 else {
00044 while ( true ) {
00045 int iPos = str.Find( ' ' );
00046 if ( iPos == -1 ) {
00047 vecKinds.push_back( str.GetBuffer( str.GetLength() ) );
00048 str.ReleaseBuffer();
00049 break;
00050 }
00051 CStringA str2 = str.Left( iPos );
00052 vecKinds.push_back( str2.GetBuffer( str2.GetLength() ) );
00053 str2.ReleaseBuffer();
00054 str = str.Right( str.GetLength() - iPos );
00055 str.TrimLeft();
00056 if ( str.IsEmpty() )
00057 break;
00058 }
00059 }
00060 }
00061
00062 bool isMetaKindMatched( const std::string& strUserKind, const std::string& strBaseType )
00063 {
00064 if ( strBaseType == FCO::string_type && ( strUserKind == Atom::string_type || strUserKind == Model::string_type ||
00065 strUserKind == Reference::string_type || strUserKind == Set::string_type || strUserKind== Connection::string_type ) )
00066 return true;
00067 return strUserKind == strBaseType;
00068 }
00069
00070 ObjectImpl* castObjectImpl( ObjectImpl* pObject, const std::string& strBEType, ObjectType eType, const std::vector<std::string>& vecKinds, const std::vector<std::string>& vecDerivedKinds )
00071 {
00072 if ( ! pObject )
00073 return NULL;
00074 if ( strBEType.empty() )
00075 {
00076 Util::Exception exc( "Invalid BON Extension Class! Check meta-kind compatibility for ?!");
00077 exc << pObject->getObjectMeta().name().c_str();
00078 ASSERTTHROW( exc);
00079 }
00080 if ( eType == OT_Null && pObject->getStereotype() == OT_Folder || eType != OT_Null && pObject->getStereotype() != eType )
00081 return NULL;
00082
00083 std::string strKind = pObject->getObjectMeta().name();
00084 std::string strRole;
00085 if ( eType != OT_Folder ) {
00086 MON::Containment role = ( (FCOImpl*) pObject )->getRole();
00087 if ( role )
00088 strRole = role.name();
00089 }
00090
00091 int i;
00092 for ( i = 0 ; i < vecKinds.size() ; i++ ) {
00093 if ( isMetaKindMatched( vecKinds[ i ], strBEType ) || vecKinds[ i ] == strKind || ! strRole.empty() && vecKinds[ i ] == strRole )
00094 return pObject;
00095 }
00096 for ( i = 0 ; i < vecDerivedKinds.size() ; i++ ) {
00097 if ( isMetaKindMatched( vecDerivedKinds[ i ], strBEType ) || vecDerivedKinds[ i ] == strKind || ! strRole.empty() && vecDerivedKinds[ i ] == strRole )
00098 return pObject;
00099 }
00100 return NULL;
00101 }
00102
00103 ExtensionType castImpl( ObjectType eOType, const std::string& strKind, const std::string& strRole, const std::string& strBEType, ObjectType eType, const std::vector<std::string>& vecKinds )
00104 {
00105 std::string strNamespacePref = NAMESPACE_PREF;
00106 if ( strBEType.empty() )
00107 {
00108 Util::Exception exc( "Invalid BON Extension Class! Check meta-kind compatibility for ?!");
00109 exc << strKind.c_str();
00110 ASSERTTHROW( exc);
00111 }
00112 ExtensionType exType = EXT_None;
00113 if ( eType != OT_Null && eOType != eType || eType == OT_Null && eOType == OT_Folder )
00114 return exType;
00115 for ( int i = 0 ; i < vecKinds.size() ; i++ ) {
00116 if ( ! strRole.empty() && ( vecKinds[ i ] == strRole || (strNamespacePref.empty()?"" : strNamespacePref + "::") + vecKinds[i] == strRole)) {
00117 return EXT_Role;
00118 }
00119 else if ( vecKinds[ i ] == strKind || (strNamespacePref.empty()?"" : strNamespacePref + "::") + vecKinds[ i ] == strKind) {
00120 if ( exType <= EXT_MetaKind )
00121 exType = EXT_Kind;
00122 }
00123 else if ( isMetaKindMatched( vecKinds[ i ], strBEType ) ) {
00124 if ( exType == EXT_None )
00125 exType = EXT_MetaKind;
00126 }
00127 }
00128 return exType;
00129 }
00130
00131 void mergeTypes( const std::string& strType1, ObjectType eType1, const std::string& strType2, ObjectType eType2, std::string& strType, ObjectType& eType )
00132 {
00133 if ( strType1.empty() || strType2.empty() ) {
00134 strType = "";
00135 eType = OT_Null;
00136 return;
00137 }
00138
00139 if ( eType2 == OT_Null ) {
00140 if (eType1 == OT_Null) {
00141 strType = strType2;
00142 eType = OT_Null;
00143 return;
00144 }
00145 mergeTypes( strType2, eType2, strType1, eType1, strType, eType );
00146 return;
00147 }
00148
00149 if ( eType1 == OT_Null && eType2 == OT_Folder || eType1 != OT_Null && eType1 != eType2 ) {
00150 strType = "";
00151 eType = OT_Null;
00152 return;
00153 }
00154
00155 strType = strType2;
00156 eType = eType2;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165 ExtensionManager::FunctionVector* ExtensionManager::_vecKindFunctions( NULL );
00166 int ExtensionManager::_vecKindFunctions_refCnt( 0 );
00167
00168 struct ExtensionsCleanup {
00169 ~ExtensionsCleanup() {
00170 delete ExtensionManager::_vecKindFunctions;
00171 ExtensionManager::_vecKindFunctions = NULL;
00172 }
00173 } cleanup;
00174
00175 ExtensionManager::ExtensionManager( const std::vector<std::string>& vecKinds, CastFunction pFnCast, CreateFunction pFnCreate )
00176 {
00177 _vecKindFunctions_refCnt++;
00178
00179
00180 ExtensionManager::vecKindFunctions().push_back( FunctionPair( pFnCast, pFnCreate ) );
00181
00182 }
00183
00184 ObjectImpl* ExtensionManager::createImpl( ObjectType eOType, const std::string& strKind, const std::string& strRole )
00185 {
00186 ExtensionType eType = EXT_None;
00187 int iLevel = 0;
00188 int iCnt = 0;
00189 int iFuncNum = 0;
00190 for ( int i = 0 ; i < ExtensionManager::vecKindFunctions().size() ; i++ ) {
00191 ExtensionInfo eInfo = (*vecKindFunctions()[ i ].first)( eOType, strKind, strRole );
00192 int iDo = 0;
00193 switch ( eInfo.first ) {
00194 case EXT_Role : {
00195 if ( eType != EXT_Role )
00196 iDo = 1;
00197 else
00198 iDo = 2;
00199 break;
00200 }
00201 case EXT_Kind : {
00202 if ( eType < EXT_Kind )
00203 iDo = 1;
00204 else
00205 if ( eType == EXT_Kind )
00206 iDo = 2;
00207 break;
00208 }
00209 case EXT_MetaKind : {
00210 if ( eType < EXT_MetaKind )
00211 iDo = 1;
00212 else
00213 if ( eType == EXT_MetaKind )
00214 iDo = 2;
00215 break;
00216 }
00217 }
00218 if ( iDo == 1 )
00219 eType = eInfo.first;
00220 if ( iDo > 0 ) {
00221 if ( iDo == 1 || iLevel < eInfo.second ) {
00222 iFuncNum = i;
00223 iCnt = 1;
00224 iLevel = eInfo.second;
00225 }
00226 else
00227 if ( iDo == 2 && iLevel == eInfo.second )
00228 iCnt++;
00229 }
00230 }
00231
00232
00233 if ( eType != EXT_None ) {
00234 if ( iCnt != 1 ) {
00235 switch ( eType ) {
00236 case EXT_Role : {
00237 Util::Exception exc( "Implementations are ambiguous for Role [?]!");
00238 exc << strRole.c_str();
00239 ASSERTTHROW( exc);
00240 break;
00241 }
00242 case EXT_Kind : {
00243 Util::Exception exc( "Implementations are ambiguous for Kind [?]!");
00244 exc << strKind.c_str();
00245 ASSERTTHROW( exc);
00246 break;
00247 }
00248 case EXT_MetaKind : {
00249 Util::Exception exc( "Implementations are ambiguous for MetaKind [?]!");
00250 exc << toString( eOType ).c_str();
00251 ASSERTTHROW( exc );
00252 break;
00253 }
00254 default:;
00255 }
00256 }
00257 return (*(vecKindFunctions())[ iFuncNum ].second)();
00258 }
00259 return NULL;
00260 }
00261
00262 };