[mapguide-commits] r1065 - in trunk/MgDev/Server/src: Common/Manager Services/Feature UnitTesting

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Mon Jan 22 19:01:30 EST 2007


Author: brucedechant
Date: 2007-01-22 19:01:30 -0500 (Mon, 22 Jan 2007)
New Revision: 1065

Modified:
   trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp
   trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h
   trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp
   trunk/MgDev/Server/src/Common/Manager/ServiceManager.h
   trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h
   trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj
   trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp
   trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h
   trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp
   trunk/MgDev/Server/src/UnitTesting/TestFeatureService.h
   trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp
Log:
Add additional performance optimizations and caching.

Modified: trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.cpp	2007-01-23 00:01:30 UTC (rev 1065)
@@ -190,7 +190,7 @@
                 {
                     // Add this entry to the cache
                     CacheFdoConnection(pFdoConnection, resourceIdentifier->ToString(),
-                                       MgUtil::MultiByteToWideChar(featureSourceXmlContent),
+                                       featureSourceXmlContent,
                                        longTransactionName);
                 }
             }
@@ -257,7 +257,7 @@
                     {
                         // Add this entry to the cache
                         STRING key = providerNameNoVersion + L" - " + connectionString;
-                        STRING data = L"";
+                        string data = "";
                         STRING ltName = L"";
                         CacheFdoConnection(pFdoConnection, key, data, ltName);
                     }
@@ -314,7 +314,27 @@
                 delete pFdoConnectionCacheEntry;
                 pFdoConnectionCacheEntry = NULL;
 
+                STRING cacheKey = iter->first;
+
+                // Remove any feature service cache entries for this resource
+                MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+                assert(NULL != serviceManager);
+
+                try
+                {
+                    Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(cacheKey);
+                    serviceManager->RemoveFeatureServiceCacheEntry(resource);
+                }
+                catch(MgInvalidRepositoryTypeException* e)
+                {
+                    // If this exception is thrown then the key was not a resource identifier string 
+                    // and so there will be no entries in the feature service cache to remove.
+                    SAFE_RELEASE(e);
+                }
+
                 m_FdoConnectionCache.erase(iter++);
+
+                ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) MgFdoConnectionManager.RemoveExpiredConnections() - Found expired cached FDO connection.\n")));
             }
             else
             {
@@ -350,7 +370,7 @@
     MgLongTransactionManager::GetLongTransactionName(resourceIdentifier, ltName);
 
     pFdoConnection = SearchFdoConnectionCache(resourceIdentifier->ToString(),
-                                              MgUtil::MultiByteToWideChar(featureSourceXmlContent),
+                                              featureSourceXmlContent,
                                               ltName);
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.FindFdoConnection")
@@ -365,9 +385,12 @@
 
     MG_FDOCONNECTION_MANAGER_TRY()
 
+    STRING providerNameNoVersion = UpdateProviderName(providerName);
+    STRING key = providerNameNoVersion + L" - " + connectionString;
+    string data = "";
     STRING ltName = L"";
 
-    pFdoConnection = SearchFdoConnectionCache(providerName, connectionString, ltName);
+    pFdoConnection = SearchFdoConnectionCache(key, data, ltName);
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.FindFdoConnection")
 
@@ -375,7 +398,7 @@
 }
 
 
-FdoIConnection* MgFdoConnectionManager::SearchFdoConnectionCache(CREFSTRING key, CREFSTRING data, CREFSTRING ltName)
+FdoIConnection* MgFdoConnectionManager::SearchFdoConnectionCache(CREFSTRING key, string& data, CREFSTRING ltName)
 {
     ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex, NULL));
 
@@ -421,6 +444,10 @@
 
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.SearchFdoConnectionCache")
 
+    #ifdef _DEBUG
+    ACE_DEBUG ((LM_DEBUG, ACE_TEXT("SearchFdoConnectionCache:\nConnection: %@\nKey = %W\nData = %W\n\n"), (void*)pFdoConnection, key.c_str(), data.empty() ? L"(empty)" : L"(data)"));
+    #endif
+
     return pFdoConnection;
 }
 
@@ -466,7 +493,6 @@
     MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.GetConnectionPropertiesFromXml")
 }
 
-
 void MgFdoConnectionManager::GetSpatialContextInfoFromXml(MgXmlUtil* pXmlUtil, MgSpatialContextInfoMap* spatialContextInfoMap)
 {
     CHECKNULL(pXmlUtil, L"MgFdoConnectionManager.GetSpatialContextInfoFromXml()");
@@ -640,21 +666,75 @@
 {
     CHECKNULL(resource, L"MgFdoConnectionManager.RetrieveFeatureSource");
 
-    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
-    assert(NULL != serviceMan);
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, sm_mutex));
 
-    // Get the service from service manager
-    Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
-        serviceMan->RequestService(MgServiceType::ResourceService));
-    assert(resourceService != NULL);
+    MG_FDOCONNECTION_MANAGER_TRY()
 
-    // Get the feature source contents
-    Ptr<MgByteReader> byteReader = resourceService->GetResourceContent(resource, MgResourcePreProcessingType::Substitution);
+    FdoConnectionCacheEntry* pFdoConnectionCacheEntry = NULL;
+    resourceContent = "";
 
-    Ptr<MgByteSink> byteSink = new MgByteSink((MgByteReader*)byteReader);
-    byteSink->ToStringUtf8(resourceContent);
+    // Check to see if we have a valid resource
+    bool bValidResource = false;
+    try
+    {
+        resource->Validate();
+        bValidResource = true;
+    }
+    catch(MgException* e)
+    {
+        SAFE_RELEASE(e);
+    }
 
-    ValidateFeatureSource(resourceContent);
+    if(bValidResource)
+    {
+        STRING key = resource->ToString();
+
+        FdoConnectionCache::iterator iter = m_FdoConnectionCache.begin();
+
+        while(m_FdoConnectionCache.end() != iter)
+        {
+            STRING cacheKey = iter->first;
+            if(ACE_OS::strcasecmp(cacheKey.c_str(), key.c_str()) == 0)
+            {
+                // We have a key match
+                pFdoConnectionCacheEntry = iter->second;
+                if(pFdoConnectionCacheEntry)
+                {
+                    resourceContent = pFdoConnectionCacheEntry->data;
+                    break;
+                }
+            }
+
+            iter++;
+        }
+    }
+
+    if(resourceContent.empty())
+    {
+        MgServiceManager* serviceMan = MgServiceManager::GetInstance();
+        assert(NULL != serviceMan);
+
+        // Get the service from service manager
+        Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
+            serviceMan->RequestService(MgServiceType::ResourceService));
+        assert(resourceService != NULL);
+
+        // Get the feature source contents
+        Ptr<MgByteReader> byteReader = resourceService->GetResourceContent(resource, MgResourcePreProcessingType::Substitution);
+
+        Ptr<MgByteSink> byteSink = new MgByteSink((MgByteReader*)byteReader);
+        byteSink->ToStringUtf8(resourceContent);
+
+        ValidateFeatureSource(resourceContent);
+
+        if(pFdoConnectionCacheEntry)
+        {
+            // Update the cache entry with the resource document now that we have it
+            pFdoConnectionCacheEntry->data = resourceContent;
+        }
+    }
+
+    MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(L"MgFdoConnectionManager.RetrieveFeatureSource")
 }
 
 
@@ -821,15 +901,12 @@
     }
 }
 
-
 MgSpatialContextInfoMap* MgFdoConnectionManager::GetSpatialContextInfo(MgResourceIdentifier* resourceIdentifier)
 {
     MgSpatialContextInfoMap* spatialContextInfoMap = NULL;
 
     MG_FDOCONNECTION_MANAGER_TRY()
 
-    ACE_TRACE ("MgFdoConnectionManager::GetSpatialContextInfo");
-
     // Retrieve XML from repository
     string featureSourceXmlContent;
     RetrieveFeatureSource(resourceIdentifier, featureSourceXmlContent);
@@ -915,6 +992,22 @@
                         delete pFdoConnectionCacheEntry;
                         pFdoConnectionCacheEntry = NULL;
 
+                        // Remove any feature service cache entries for this resource
+                        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+                        assert(NULL != serviceManager);
+
+                        try
+                        {
+                            Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier(key);
+                            serviceManager->RemoveFeatureServiceCacheEntry(resource);
+                        }
+                        catch(MgInvalidRepositoryTypeException* e)
+                        {
+                            // If this exception is thrown then the key was not a resource identifier string 
+                            // and so there will be no entries in the feature service cache to remove.
+                            SAFE_RELEASE(e);
+                        }
+
                         m_FdoConnectionCache.erase(iter++);
 
                         connectionsRemoved++;
@@ -954,8 +1047,7 @@
     return (connections == connectionsRemoved);
 }
 
-
-void MgFdoConnectionManager::CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING key, CREFSTRING data, CREFSTRING ltName)
+void MgFdoConnectionManager::CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING key, string& data, CREFSTRING ltName)
 {
     MG_FDOCONNECTION_MANAGER_TRY()
 
@@ -971,6 +1063,10 @@
         pFdoConnectionCacheEntry->pFdoConnection = pFdoConnection;
         pFdoConnectionCacheEntry->lastUsed = ACE_OS::gettimeofday();
 
+        #ifdef _DEBUG
+        ACE_DEBUG ((LM_DEBUG, ACE_TEXT("CacheFdoConnection:\nConnection: %@\nKey = %W\nData = %W\n\n"), (void*)pFdoConnection, key.c_str(), data.empty() ? L"(empty)" : L"(data)"));
+        #endif
+
         m_FdoConnectionCache.insert(FdoConnectionCache_Pair(key, pFdoConnectionCacheEntry));
 
         // Increase the reference count before returning it because this entry has been cached

Modified: trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Common/Manager/FdoConnectionManager.h	2007-01-23 00:01:30 UTC (rev 1065)
@@ -37,7 +37,7 @@
 #define MG_FDOCONNECTION_MANAGER_CATCH_AND_THROW(methodName)   MG_FEATURE_SERVICE_CATCH_AND_THROW(methodName)
 
 typedef struct {
-    STRING data;    // XML content or connection string
+    string data;    // Feature source XML content
     STRING ltName;  // current long transaction name for this connection
     FdoIConnection* pFdoConnection;
     ACE_Time_Value lastUsed;
@@ -73,6 +73,8 @@
     MgSpatialContextInfoMap* GetSpatialContextInfo(MgResourceIdentifier* resourceIdentifier);
     STRING UpdateProviderName(CREFSTRING providerName);
 
+    void RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent);
+
     void RemoveExpiredConnections();
     bool RemoveCachedFdoConnection(CREFSTRING key);
 
@@ -86,11 +88,10 @@
 
     FdoIConnection* FindFdoConnection(MgResourceIdentifier* resourceIdentifier);
     FdoIConnection* FindFdoConnection(CREFSTRING providerName, CREFSTRING connectionString);
-    FdoIConnection* SearchFdoConnectionCache(CREFSTRING key, CREFSTRING data, CREFSTRING ltName);
-    void CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING key, CREFSTRING data, CREFSTRING ltName);
+    FdoIConnection* SearchFdoConnectionCache(CREFSTRING key, string& data, CREFSTRING ltName);
+    void CacheFdoConnection(FdoIConnection* pFdoConnection, CREFSTRING key, string& data, CREFSTRING ltName);
     bool FdoConnectionCacheFull(void);
 
-    void RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent);
     void GetConnectionPropertiesFromXml(MgXmlUtil* pXmlUtil, STRING& providerName, STRING& configDocumentName, STRING& longTransactionName);
     void GetSpatialContextInfoFromXml(MgXmlUtil* pXmlUtil, MgSpatialContextInfoMap* spatialContextInfoMap);
 

Modified: trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Common/Manager/ServiceManager.cpp	2007-01-23 00:01:30 UTC (rev 1065)
@@ -476,3 +476,22 @@
 
     MG_CATCH(L"MgServiceManager.NotifyFeatureServiceCache")
 }
+
+///////////////////////////////////////////////////////////////////////////////
+/// \brief
+/// Remove the resource from the feature service cache.
+///
+void MgServiceManager::RemoveFeatureServiceCacheEntry(MgResourceIdentifier* resource)
+{
+    MG_TRY()
+
+    Ptr<MgServerFeatureService> featureService = dynamic_cast<MgServerFeatureService*>(
+        RequestLocalService(MgServiceType::FeatureService));
+
+    if (featureService != NULL)
+    {
+        featureService->RemoveFeatureServiceCacheEntry(resource);
+    }
+
+    MG_CATCH(L"MgServiceManager.NotifyFeatureServiceCache")
+}

Modified: trunk/MgDev/Server/src/Common/Manager/ServiceManager.h
===================================================================
--- trunk/MgDev/Server/src/Common/Manager/ServiceManager.h	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Common/Manager/ServiceManager.h	2007-01-23 00:01:30 UTC (rev 1065)
@@ -58,6 +58,7 @@
     void DispatchResourceChangeNotifications();
 
     void NotifyFeatureServiceCache();
+    void RemoveFeatureServiceCacheEntry(MgResourceIdentifier* resource);
 
 private:
 

Modified: trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.cpp	2007-01-23 00:01:30 UTC (rev 1065)
@@ -1630,54 +1630,12 @@
 {
     CHECKNULL(resource, L"MgServerDescribeSchema.RetrieveFeatureSource");
 
-    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
-    assert(NULL != serviceMan);
+    resourceContent = "";
 
-    // Get the service from service manager
-    Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
-        serviceMan->RequestService(MgServiceType::ResourceService));
-    assert(resourceService != NULL);
-
-    // Get the feature source contents
-    Ptr<MgByteReader> byteReader = resourceService->GetResourceContent(resource, MgResourcePreProcessingType::Substitution);
-
-    Ptr<MgByteSink> byteSink = new MgByteSink((MgByteReader*)byteReader);
-    byteSink->ToStringUtf8(resourceContent);
-
-    ValidateFeatureSource(resourceContent);
-}
-
-void MgServerDescribeSchema::ValidateFeatureSource(string& featureSourceXmlContent)
-{
-    bool isValidFeatureSource = true;
-
-    // TODO: Should we add XML validation here to ensure the integrity of feature source
-    if (featureSourceXmlContent.empty())
+    // Get the feature source XML content document from the FDO connection manager.
+    MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
+    if(pFdoConnectionManager)
     {
-        isValidFeatureSource = false;
+         pFdoConnectionManager->RetrieveFeatureSource(resource, resourceContent);
     }
-    else
-    {
-        int index = (int)featureSourceXmlContent.find("<FeatureSource");
-        if (index == -1)
-        {
-            isValidFeatureSource = false;
-        }
-    }
-
-    // if invalid FeatureSource, throw exception saying invalid provider specified
-    if (!isValidFeatureSource)
-    {
-        STRING message = MgUtil::GetResourceMessage(MgResources::FeatureService, L"MgInvalidFdoProvider");
-
-        Ptr<MgStringCollection> strCol = (MgStringCollection*)NULL;
-        if (!message.empty())
-        {
-            strCol = new MgStringCollection();
-            strCol->Add(message);
-        }
-
-        throw new MgInvalidFeatureSourceException(L"MgServerDescribeSchema.ValidateFeatureSource",
-            __LINE__, __WFILE__, (MgStringCollection*)strCol, L"", NULL);
-    }
 }

Modified: trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Services/Feature/ServerDescribeSchema.h	2007-01-23 00:01:30 UTC (rev 1065)
@@ -60,7 +60,6 @@
     STRING GetSerializedXml(FdoFeatureSchemaCollection* fdoSchemaCol);
 
     void RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent);
-    void ValidateFeatureSource(string& featureSourceXmlContent);
 };
 
 #endif

Modified: trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Services/Feature/ServerFeatureService.vcproj	2007-01-23 00:01:30 UTC (rev 1065)
@@ -66,7 +66,7 @@
 				OutputFile="$(OutDir)\MgServerFeatureServiced.dll"
 				LinkIncremental="2"
 				AdditionalLibraryDirectories="..\..\..\..\Oem\ACE\ACE_wrappers\lib;&quot;..\..\..\..\Oem\dbxml-2.2.13\lib&quot;;..\..\..\..\Oem\FDO\lib;..\..\..\lib\debug"
-				DelayLoadDLLs="Fdo.dll;FdoCommon.dll"
+				DelayLoadDLLs="Fdo.dll;FdoCommon.dll;FdoGeometry.dll"
 				GenerateDebugInformation="true"
 				ProgramDatabaseFile="$(OutDir)/MgServerFeatureServiced.pdb"
 				SubSystem="2"

Modified: trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.cpp	2007-01-23 00:01:30 UTC (rev 1065)
@@ -46,7 +46,7 @@
     FDO_SAFE_RELEASE(m_customFunction);
 }
 
-// Executes the describe schema command and serializes the schema to XML
+// Executes the select features command and serializes the reader
 MgReader* MgServerSelectFeatures::SelectFeatures(MgResourceIdentifier* resource,
                                                  CREFSTRING className,
                                                  MgFeatureQueryOptions* options,
@@ -60,8 +60,16 @@
     // Validate parameters
     ValidateParam(resource,className);
 
+    // Retrieve the feature source XML document
+    string featureSourceXmlContent;
+    RetrieveFeatureSource(resource, featureSourceXmlContent);
+
+    // Parse the feature source XML document so that it will be ready to be walked for needed property information
+    m_xmlUtil.ParseString(featureSourceXmlContent.c_str());
+
     // Check if a feature join is to be performed by inspecting the resource for join properties
-    if (!isSelectAggregate && FindFeatureJoinProperties(resource, className))
+    bool bFeatureJoinProperties = FindFeatureJoinProperties(resource, className);
+    if (!isSelectAggregate && bFeatureJoinProperties)
     {
         // Get the FdoFilter from the options
         // Create Command
@@ -116,7 +124,7 @@
         ApplyQueryOptions(isSelectAggregate);
 
         // Check if the specified className is an extension (join) in the feature source
-        if (FindFeatureJoinProperties(resource, className))
+        if (bFeatureJoinProperties)
         {
             // Perform feature join to obtain the joined properties
             Ptr<MgServerGwsFeatureReader> gwsFeatureReader = JoinFeatures(resource, className, NULL);
@@ -361,6 +369,17 @@
 
         FdoPtr<FdoByteArray> byteArray = FdoByteArray::Create(gisBytes, (FdoInt32)len);
 
+        #ifdef _DEBUG
+        // Get the spatial filter geometry text
+        FdoFgfGeometryFactory* geometryFactory = FdoFgfGeometryFactory::GetInstance();
+        if(geometryFactory)
+        {
+            FdoPtr<FdoIGeometry> geometry = geometryFactory->CreateGeometryFromFgf(byteArray);
+            STRING geomText = geometry->GetText();
+            ACE_DEBUG((LM_ERROR, ACE_TEXT("SPATIAL FILTER: %W\n"), geomText.c_str()));
+        }
+        #endif
+
         FdoPtr<FdoGeometryValue> geomValue = FdoGeometryValue::Create(byteArray);
         if (geomValue != NULL)
         {
@@ -758,18 +777,9 @@
 {
     bool bJoinPropertiesExists = false;
 
-    //// Parse the resource identifier to get the join parameters
-    // Retrieve XML from repository
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(resourceId, featureSourceXmlContent);
+    DOMElement* rootNode = m_xmlUtil.GetRootNode();
+    DOMNodeList* extensionNodeList = m_xmlUtil.GetNodeList(rootNode, "Extension" /* NOXLATE */ );
 
-    // Needed to parse XML and get properties
-    MgXmlUtil xmlUtil;
-    xmlUtil.ParseString(featureSourceXmlContent.c_str());
-
-    DOMElement* rootNode = xmlUtil.GetRootNode();
-    DOMNodeList* extensionNodeList = xmlUtil.GetNodeList(rootNode, "Extension" /* NOXLATE */ );
-
     if (NULL != extensionNodeList)
     {
         int extensionNodes = (int)extensionNodeList->getLength();
@@ -779,7 +789,7 @@
             DOMNode* extensionNode = extensionNodeList->item(i);
             CHECKNULL(extensionNode, L"MgServerSelectFeatures.FindFeatureJoinProperties");
 
-            DOMNodeList* nameNodeList = xmlUtil.GetNodeList(extensionNode, "Name");
+            DOMNodeList* nameNodeList = m_xmlUtil.GetNodeList(extensionNode, "Name");
             int nNameNodes = (int)nameNodeList->getLength();
 
             // get the extension name node
@@ -787,7 +797,7 @@
 
             // get the extension name value
             STRING name;
-            xmlUtil.GetTextFromElement((DOMElement*)extensionNameNode, name);
+            m_xmlUtil.GetTextFromElement((DOMElement*)extensionNameNode, name);
 
             STRING parsedSchemaName = L"";
             STRING parsedExtensionName = L"";
@@ -816,17 +826,8 @@
     FdoPtr<IGWSQueryDefinition> qd;
     FdoPtr<MgGwsConnectionPool> pool = MgGwsConnectionPool::Create();
 
-    //// Parse the resource identifier to get the join parameters
-    // Retrieve XML from repository
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(featureSourceIdentifier, featureSourceXmlContent);
-
-    // Needed to parse XML and get properties
-    MgXmlUtil xmlUtil;
-    xmlUtil.ParseString(featureSourceXmlContent.c_str());
-
-    DOMElement* rootNode = xmlUtil.GetRootNode();
-    DOMNodeList* extensionNodeList = xmlUtil.GetNodeList(rootNode, "Extension" /* NOXLATE */ );
+    DOMElement* rootNode = m_xmlUtil.GetRootNode();
+    DOMNodeList* extensionNodeList = m_xmlUtil.GetNodeList(rootNode, "Extension" /* NOXLATE */ );
     CHECKNULL(extensionNodeList, L"MgServerSelectFeatures.JoinFeatures");
 
     int extensionNodes = (int)extensionNodeList->getLength();
@@ -836,7 +837,7 @@
         DOMNode* extensionNode = extensionNodeList->item(i);
         CHECKNULL(extensionNode, L"MgServerSelectFeatures.JoinFeatures");
 
-        DOMNodeList* nameNodeList = xmlUtil.GetNodeList(extensionNode, "Name");
+        DOMNodeList* nameNodeList = m_xmlUtil.GetNodeList(extensionNode, "Name");
         int nNameNodes = (int)nameNodeList->getLength();
 
         // get the extension name node
@@ -844,7 +845,7 @@
 
         // get the extension name value
         STRING name;
-        xmlUtil.GetTextFromElement((DOMElement*)extensionNameNode, name);
+        m_xmlUtil.GetTextFromElement((DOMElement*)extensionNameNode, name);
 
         STRING parsedSchemaName = L"";
         STRING parsedExtensionName = L"";
@@ -873,7 +874,7 @@
 
             // Retrieve the primary feature class
             wstring szFeatureClass;
-            xmlUtil.GetElementValue(extensionNode, "FeatureClass", szFeatureClass);
+            m_xmlUtil.GetElementValue(extensionNode, "FeatureClass", szFeatureClass);
 
             // Parse the qualified classname
             STRING primaryFsSchema = L"";
@@ -894,7 +895,7 @@
             IGWSJoinQueryDefinition* jqd = NULL;
 
             // Determine the number of secondary sources (AttributeRelate nodes)
-            DOMNodeList* attributeRelateNodeList = xmlUtil.GetNodeList(extensionNode, "AttributeRelate");
+            DOMNodeList* attributeRelateNodeList = m_xmlUtil.GetNodeList(extensionNode, "AttributeRelate");
             int nAttributeRelateNodes = (int)attributeRelateNodeList->getLength();
 
             // For each join to a secondary source need to do the following
@@ -906,16 +907,16 @@
 
                 // Get the secondary resource id
                 wstring szSecondaryResourceId;
-                xmlUtil.GetElementValue(attributeRelateNode, "ResourceId", szSecondaryResourceId);
+                m_xmlUtil.GetElementValue(attributeRelateNode, "ResourceId", szSecondaryResourceId);
 
                 // Get the name for the join relationship
                 wstring szAttributeRelateName;
-                xmlUtil.GetElementValue(attributeRelateNode, "Name", szAttributeRelateName);
+                m_xmlUtil.GetElementValue(attributeRelateNode, "Name", szAttributeRelateName);
                 STRING secondaryConnectionName = szAttributeRelateName;
 
                 // Get the RelateType (join type).  Default is Left Outer join.
                 wstring szRelateType;
-                xmlUtil.GetElementValue(attributeRelateNode, "RelateType", szRelateType, false);
+                m_xmlUtil.GetElementValue(attributeRelateNode, "RelateType", szRelateType, false);
                 if (szRelateType.empty())
                 {
                     szRelateType = L"LeftOuter";     // NOXLATE
@@ -924,7 +925,7 @@
                 // Get the ForceOneToOne field, which specifies if multiple matching secondary features 
                 // are retrieved via a 1-to-1 or 1-to-many relationship.  Default is 1-to-1 relationship.
                 wstring szForceOneToOne;
-                xmlUtil.GetElementValue(attributeRelateNode, "ForceOneToOne", szForceOneToOne, false);
+                m_xmlUtil.GetElementValue(attributeRelateNode, "ForceOneToOne", szForceOneToOne, false);
                 if (szForceOneToOne.empty())
                 {
                     szForceOneToOne = L"true";     // NOXLATE
@@ -938,7 +939,7 @@
                 // Get the AttributeNameDelimiter field, which specifies the delimiter between the JoinName (attribute relate name)
                 // and the property name for an extended property.  Default delimiter is "" (blank).
                 wstring szAttributeNameDelimiter;
-                xmlUtil.GetElementValue(attributeRelateNode, "AttributeNameDelimiter", szAttributeNameDelimiter, false);
+                m_xmlUtil.GetElementValue(attributeRelateNode, "AttributeNameDelimiter", szAttributeNameDelimiter, false);
                 STRING attributeNameDelimiter = szAttributeNameDelimiter;
                 attributeNameDelimiters->Add(attributeNameDelimiter);
 
@@ -962,7 +963,7 @@
 
                 // Get the secondary feature className (qualified className)
                 wstring szSecondaryClassName;
-                xmlUtil.GetElementValue(attributeRelateNode, "AttributeClass", szSecondaryClassName);
+                m_xmlUtil.GetElementValue(attributeRelateNode, "AttributeClass", szSecondaryClassName);
 
                 // Parse the qualifed classname
                 STRING secondaryFsSchema = L"";
@@ -984,7 +985,7 @@
                 FdoPtr<FdoStringCollection> rattrs = FdoStringCollection::Create();
 
                 // Determine the number of ReleateProperties (attributes)
-                DOMNodeList* relatePropertyNodeList = xmlUtil.GetNodeList(attributeRelateNode, "RelateProperty");
+                DOMNodeList* relatePropertyNodeList = m_xmlUtil.GetNodeList(attributeRelateNode, "RelateProperty");
                 int nRelatePropertyNodes = relatePropertyNodeList->getLength();
 
                 // For each RelateProperty need to do the following
@@ -994,14 +995,14 @@
 
                     // Get the FeatureClassProperty (primary attribute)
                     wstring szPrimaryAttribute;
-                    xmlUtil.GetElementValue(relatePropertyNode, "FeatureClassProperty", szPrimaryAttribute);
+                    m_xmlUtil.GetElementValue(relatePropertyNode, "FeatureClassProperty", szPrimaryAttribute);
 
                     // Add to the primary attribute String collection
                     lattrs->Add(szPrimaryAttribute.c_str());
 
                     // Get the AttributeClassProperty (secondary attribute)
                     wstring szSecondaryAttribute;
-                    xmlUtil.GetElementValue(relatePropertyNode, "AttributeClassProperty", szSecondaryAttribute);
+                    m_xmlUtil.GetElementValue(relatePropertyNode, "AttributeClassProperty", szSecondaryAttribute);
 
                     // Add to the secondary attribute String collection
                     rattrs->Add(szSecondaryAttribute.c_str());
@@ -1052,21 +1053,14 @@
 {
     CHECKNULL(resource, L"MgServerSelectFeatures.RetrieveFeatureSource");
 
-    MgServiceManager* serviceMan = MgServiceManager::GetInstance();
-    assert(NULL != serviceMan);
+    resourceContent = "";
 
-    // Get the service from service manager
-    Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
-        serviceMan->RequestService(MgServiceType::ResourceService));
-    assert(resourceService != NULL);
-
-    // Get the feature source contents
-    Ptr<MgByteReader> byteReader = resourceService->GetResourceContent(resource, MgResourcePreProcessingType::Substitution);
-
-    Ptr<MgByteSink> byteSink = new MgByteSink((MgByteReader*)byteReader);
-    byteSink->ToStringUtf8(resourceContent);
-
-    ValidateFeatureSource(resourceContent);
+    // Get the feature source XML content document from the FDO connection manager.
+    MgFdoConnectionManager* pFdoConnectionManager = MgFdoConnectionManager::GetInstance();
+    if(pFdoConnectionManager)
+    {
+         pFdoConnectionManager->RetrieveFeatureSource(resource, resourceContent);
+    }
 }
 
 
@@ -1078,56 +1072,13 @@
     className = qualifiedClassName.substr(nIndex+1);
 }
 
-void MgServerSelectFeatures::ValidateFeatureSource(string& featureSourceXmlContent)
-{
-    bool isValidFeatureSource = true;
-
-    // TODO: Should we add XML validation here to ensure the integrity of feature source
-    if (featureSourceXmlContent.empty())
-    {
-        isValidFeatureSource = false;
-    }
-    else
-    {
-        int index = (int)featureSourceXmlContent.find("<FeatureSource");
-        if (index == -1)
-        {
-            isValidFeatureSource = false;
-        }
-    }
-
-    // if invalid FeatureSource, throw exception saying invalid provider specified
-    if (!isValidFeatureSource)
-    {
-        STRING message = MgUtil::GetResourceMessage(MgResources::FeatureService, L"MgInvalidFdoProvider");
-
-        Ptr<MgStringCollection> strCol = (MgStringCollection*)NULL;
-        if (!message.empty())
-        {
-            strCol = new MgStringCollection();
-            strCol->Add(message);
-        }
-
-        throw new MgInvalidFeatureSourceException(L"MgServerSelectFeatures.ValidateFeatureSource",
-            __LINE__, __WFILE__, (MgStringCollection*)strCol, L"", NULL);
-    }
-}
-
 MgResourceIdentifier* MgServerSelectFeatures::GetSecondaryResourceIdentifier(MgResourceIdentifier* primResId, CREFSTRING extensionName, CREFSTRING relationName)
 {
     Ptr<MgResourceIdentifier> secResId;
 
-    // look in the xml to find the resource for the specified relation
-    string featureSourceXmlContent;
-    RetrieveFeatureSource(primResId, featureSourceXmlContent);
+    DOMElement* rootNode = m_xmlUtil.GetRootNode();
+    DOMNodeList* extensionNodeList = m_xmlUtil.GetNodeList(rootNode, "Extension" /* NOXLATE */ );
 
-    // Needed to parse XML and get properties
-    MgXmlUtil xmlUtil;
-    xmlUtil.ParseString(featureSourceXmlContent.c_str());
-
-    DOMElement* rootNode = xmlUtil.GetRootNode();
-    DOMNodeList* extensionNodeList = xmlUtil.GetNodeList(rootNode, "Extension" /* NOXLATE */ );
-
     if (NULL != extensionNodeList)
     {
         int extensionNodes = (int)extensionNodeList->getLength();
@@ -1137,7 +1088,7 @@
             DOMNode* extensionNode = extensionNodeList->item(i);
             CHECKNULL(extensionNode, L"MgServerSelectFeatures.GetSecondaryResourceIdentifier");
 
-            DOMNodeList* nameNodeList = xmlUtil.GetNodeList(extensionNode, "Name");
+            DOMNodeList* nameNodeList = m_xmlUtil.GetNodeList(extensionNode, "Name");
             int nNameNodes = (int)nameNodeList->getLength();
 
             // get the extension name node
@@ -1145,7 +1096,7 @@
 
             // get the extension name value
             STRING name;
-            xmlUtil.GetTextFromElement((DOMElement*)extensionNameNode, name);
+            m_xmlUtil.GetTextFromElement((DOMElement*)extensionNameNode, name);
 
             STRING parsedSchemaName = L"";
             STRING parsedExtensionName = L"";
@@ -1158,7 +1109,7 @@
             else
             {
                 // Determine the number of secondary sources (AttributeRelate nodes)
-                DOMNodeList* attributeRelateNodeList = xmlUtil.GetNodeList(extensionNode, "AttributeRelate");
+                DOMNodeList* attributeRelateNodeList = m_xmlUtil.GetNodeList(extensionNode, "AttributeRelate");
                 int nAttributeRelateNodes = (int)attributeRelateNodeList->getLength();
 
                 // Find the the specified relation name
@@ -1168,7 +1119,7 @@
 
                     // Get the name for the join relationship
                     wstring szAttributeRelateName;
-                    xmlUtil.GetElementValue(attributeRelateNode, "Name", szAttributeRelateName);
+                    m_xmlUtil.GetElementValue(attributeRelateNode, "Name", szAttributeRelateName);
 
                     if ( szAttributeRelateName != relationName )
                     {
@@ -1178,7 +1129,7 @@
                     {
                         // Get the secondary resource id
                         wstring szSecondaryResourceId;
-                        xmlUtil.GetElementValue(attributeRelateNode, "ResourceId", szSecondaryResourceId);
+                        m_xmlUtil.GetElementValue(attributeRelateNode, "ResourceId", szSecondaryResourceId);
                         secResId = new MgResourceIdentifier(szSecondaryResourceId);
                         break;
                     }

Modified: trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h
===================================================================
--- trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/Services/Feature/ServerSelectFeatures.h	2007-01-23 00:01:30 UTC (rev 1065)
@@ -39,6 +39,7 @@
                              MgFeatureQueryOptions* options,
                              bool isSelectAggregate);
 
+private:
     void  ApplyQueryOptions(bool isSelectAggregate);
     void  ApplyClassProperties();
     void  ApplyComputedProperties();
@@ -50,8 +51,6 @@
     //FdoFunction* GetCustomFunction() { return FDO_SAFE_ADDREF(m_customFunction); }
     //STRING GetCustomPropertyName() { return m_customPropertyName; }
 
-private:
-
     bool IsFdoSupportedFunction(FdoIConnection* connection, FdoFunction* fdoFunc);
     bool ContainsUdf(FdoExpression* expression);
     bool IsCustomFunction(FdoFunction* fdoFunc);
@@ -71,6 +70,7 @@
     Ptr<MgFeatureQueryOptions> m_options;
     STRING                  filterText;
     Ptr<MgFeatureServiceCommand>    m_command;
+    MgXmlUtil m_xmlUtil;
 
     // Only one custom property is supported. No nesting of custom properties allowed.
     STRING                  m_customPropertyName;
@@ -82,7 +82,6 @@
     MgServerGwsFeatureReader* JoinFeatures(MgResourceIdentifier* featureSourceId, CREFSTRING extensionName, FdoFilter* filter);
     void RetrieveFeatureSource(MgResourceIdentifier* resource, string& resourceContent);
     void ParseQualifiedClassName(CREFSTRING qualifiedClassName, STRING& schemaName, STRING& className);
-    void ValidateFeatureSource(string& featureSourceXmlContent);
     MgResourceIdentifier* GetSecondaryResourceIdentifier(MgResourceIdentifier* primResId, CREFSTRING extensionName, CREFSTRING relationName);
 };
 

Modified: trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/UnitTesting/TestFeatureService.cpp	2007-01-23 00:01:30 UTC (rev 1065)
@@ -24,6 +24,17 @@
 #include "ServerFeatureService.h"
 #include "Fdo.h"
 
+#ifndef _WIN32
+// Linux version of GetTickCount()
+#include <sys/times.h>
+
+long GetTickCount()
+{
+    tms tm;
+    return times(&tm);
+}
+#endif
+
 const STRING TEST_LOCALE = L"en";
 
 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(TestFeatureService, "TestFeatureService");
@@ -290,7 +301,7 @@
         Ptr<MgUserInformation> adminUserInfo = new MgUserInformation(MgUser::Administrator, L"");
         MgUserInformation::SetCurrentUserInfo(adminUserInfo);
 
-        const STRING provider = L"OSGeo.SDF.3.2";
+        const STRING provider = L"OSGeo.SDF";
 #ifdef _WIN32
         const STRING connectionString = L"File=..\\UnitTestFiles\\Sheboygan_Parcels.sdf";
 #else
@@ -332,7 +343,7 @@
             throw new MgNullReferenceException(L"TestFeatureService.TestCase_TestFdoConnectionManager", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
-        const STRING provider = L"OSGeo.SDF.3.2";
+        const STRING provider = L"OSGeo.SDF";
 #ifdef _WIN32
         const STRING connectionString = L"File=..\\UnitTestFiles\\Sheboygan_Parcels.sdf";
 #else
@@ -401,7 +412,7 @@
         CPPUNIT_ASSERT_THROW_MG(pService->GetConnectionPropertyValues(provider, property, connectionString),
             MgInvalidArgumentException*);
 
-        provider = L"OSGeo.SDF.3.2";
+        provider = L"OSGeo.SDF";
         property = L"ReadOnly";
         Ptr<MgStringCollection> properties = pService->GetConnectionPropertyValues(provider, property, connectionString);
         CPPUNIT_ASSERT(properties->GetCount() > 0);
@@ -445,7 +456,7 @@
             throw new MgServiceNotAvailableException(L"TestFeatureService.TestCase_GetCapabilities", __LINE__, __WFILE__, NULL, L"", NULL);
         }
 
-        STRING provider = L"OSGeo.SDF.3.2";
+        STRING provider = L"OSGeo.SDF";
 
         MgFdoConnectionManager* fdoConnectionManager = MgFdoConnectionManager::GetInstance();
         if(fdoConnectionManager == 0)
@@ -1673,3 +1684,65 @@
         throw;
     }
 }
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// This test case benchmarks selecting features.
+///----------------------------------------------------------------------------
+void TestFeatureService::TestCase_BenchmarkSelectFeatures()
+{
+    try
+    {
+        ACE_DEBUG((LM_INFO, ACE_TEXT("\nTestCase_BenchmarkSelectFeatures - START\n")));
+        MgServiceManager* serviceManager = MgServiceManager::GetInstance();
+        if(serviceManager == 0)
+        {
+            throw new MgNullReferenceException(L"TestFeatureService.TestCase_BenchmarkSelectFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        Ptr<MgFeatureService> pService = dynamic_cast<MgFeatureService*>(serviceManager->RequestService(MgServiceType::FeatureService));
+        if (pService == 0)
+        {
+            throw new MgServiceNotAvailableException(L"TestFeatureService.TestCase_BenchmarkSelectFeatures", __LINE__, __WFILE__, NULL, L"", NULL);
+        }
+
+        Ptr<MgResourceIdentifier> resource = new MgResourceIdentifier();
+        STRING className = L"Parcels";
+        resource = new MgResourceIdentifier(L"Library://UnitTests/Data/Sheboygan_Parcels.FeatureSource");
+        Ptr<MgFeatureQueryOptions> options = new MgFeatureQueryOptions();
+
+        const int iterations = 1000;
+        long lStart = GetTickCount();
+        for(int i=0;i<iterations;i++)
+        {
+            int nFeatures = 0;
+            Ptr<MgFeatureReader> reader = pService->SelectFeatures(resource, className, options);
+            while(reader->ReadNext())
+            {
+                nFeatures++;
+            }
+
+            reader->Close();
+            CPPUNIT_ASSERT(nFeatures == 17565);
+        }
+
+        ACE_DEBUG((LM_INFO, ACE_TEXT("  Execution Time (Average of %d runs): = %6.4f (s)\n"), iterations, ((GetTickCount()-lStart)/1000.0)/(double)iterations ));
+        ACE_DEBUG((LM_INFO, ACE_TEXT("TestCase_BenchmarkSelectFeatures - END\n")));
+    }
+    catch(MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch(FdoException* e)
+    {
+        FDO_SAFE_RELEASE(e);
+        CPPUNIT_FAIL("FdoException occured");
+    }
+    catch(...)
+    {
+        throw;
+    }
+}

Modified: trunk/MgDev/Server/src/UnitTesting/TestFeatureService.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestFeatureService.h	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/UnitTesting/TestFeatureService.h	2007-01-23 00:01:30 UTC (rev 1065)
@@ -54,6 +54,7 @@
     CPPUNIT_TEST(TestCase_JoinFeatures);
     CPPUNIT_TEST(TestCase_JoinFeaturesChainedInner1ToMany);
     CPPUNIT_TEST(TestCase_CreateFeatureSource);
+    CPPUNIT_TEST(TestCase_BenchmarkSelectFeatures);
 
     CPPUNIT_TEST(TestEnd); // This must be the very last unit test
     CPPUNIT_TEST_SUITE_END();
@@ -93,6 +94,7 @@
     void TestCase_JoinFeatures();
     void TestCase_JoinFeaturesChainedInner1ToMany();
     void TestCase_CreateFeatureSource();
+    void TestCase_BenchmarkSelectFeatures();
 };
 
 #endif // _TESTFEATURESERVICE_H

Modified: trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp	2007-01-20 00:49:25 UTC (rev 1064)
+++ trunk/MgDev/Server/src/UnitTesting/TestTileService.cpp	2007-01-23 00:01:30 UTC (rev 1065)
@@ -280,7 +280,6 @@
     {
         STRING message = e->GetDetails(TEST_LOCALE);
         SAFE_RELEASE(e);
-        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
     }
     catch (...)
     {



More information about the mapguide-commits mailing list