Add metadata observation hook.
authorScott Cantor <cantor.2@osu.edu>
Sun, 13 Aug 2006 01:32:49 +0000 (01:32 +0000)
committerScott Cantor <cantor.2@osu.edu>
Sun, 13 Aug 2006 01:32:49 +0000 (01:32 +0000)
saml/Makefile.am
saml/saml.vcproj
saml/saml2/metadata/MetadataProvider.h
saml/saml2/metadata/ObservableMetadataProvider.h [new file with mode: 0644]
saml/saml2/metadata/impl/FilesystemMetadataProvider.cpp
saml/saml2/metadata/impl/MetadataProvider.cpp
saml/saml2/metadata/impl/ObservableMetadataProvider.cpp [new file with mode: 0644]

index 31abc1a..36e8611 100644 (file)
@@ -49,7 +49,8 @@ saml2coreinclude_HEADERS = \
 saml2mdinclude_HEADERS = \
        saml2/metadata/Metadata.h
        saml2/metadata/MetadataFilter.h \
-       saml2/metadata/MetadataProvider.h
+       saml2/metadata/MetadataProvider.h \
+       saml2/metadata/ObservableMetadataProvider.h
 
 noinst_HEADERS = \
        internal.h
@@ -75,6 +76,7 @@ libsaml_la_SOURCES = \
        saml2/metadata/impl/MetadataImpl.cpp \
        saml2/metadata/impl/MetadataProvider.cpp \
        saml2/metadata/impl/MetadataSchemaValidators.cpp \
+       saml2/metadata/impl/ObservableMetadataProvider.cpp \
        saml2/metadata/impl/WhitelistMetadataFilter.cpp \
        signature/ContentReference.cpp \
        signature/SignatureProfileValidator.cpp \
index 58ba323..ce4d609 100644 (file)
                                                        >\r
                                                </File>\r
                                                <File\r
+                                                       RelativePath=".\saml2\metadata\impl\ObservableMetadataProvider.cpp"\r
+                                                       >\r
+                                               </File>\r
+                                               <File\r
                                                        RelativePath=".\saml2\metadata\impl\WhitelistMetadataFilter.cpp"\r
                                                        >\r
                                                </File>\r
                                                RelativePath=".\saml2\metadata\MetadataProvider.h"\r
                                                >\r
                                        </File>\r
+                                       <File\r
+                                               RelativePath=".\saml2\metadata\ObservableMetadataProvider.h"\r
+                                               >\r
+                                       </File>\r
                                </Filter>\r
                        </Filter>\r
                        <Filter\r
index 7f5d386..1c2765e 100644 (file)
@@ -199,7 +199,7 @@ namespace opensaml {
             /**
              * Clear the cache of known entities and groups.
              */
-            virtual void clearIndex();
+            virtual void clearDescriptorIndex();
         
         private:
             std::vector<MetadataFilter*> m_filters;
diff --git a/saml/saml2/metadata/ObservableMetadataProvider.h b/saml/saml2/metadata/ObservableMetadataProvider.h
new file mode 100644 (file)
index 0000000..e1b1ae5
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  Copyright 2001-2006 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file saml/saml2/metadata/ObservableMetadataProvider.h
+ * 
+ * A metadata provider that notifies interested parties of changes.
+ */
+
+#ifndef __saml2_obsmetadataprov_h__
+#define __saml2_obsmetadataprov_h__
+
+#include <saml/saml2/metadata/MetadataProvider.h>
+
+namespace opensaml {
+    
+    namespace saml2md {
+        
+        /**
+         * A metadata provider that notifies interested parties of changes.
+         */
+        class SAML_API ObservableMetadataProvider : public MetadataProvider
+        {
+        protected:
+            /**
+             * Constructor.
+             * 
+             * @param e DOM to supply configuration for provider
+             */
+            ObservableMetadataProvider(const DOMElement* e) : MetadataProvider(e) {}
+            
+            /**
+             * Convenience method for notifying every registered Observer of an event.
+             */
+            void emitChangeEvent();
+
+        public:
+            /**
+             * Destructor will delete any installed filters.
+             */
+            virtual ~ObservableMetadataProvider();
+            
+            /**
+             * An observer of metadata provider changes.
+             */
+            class SAML_API Observer {
+                MAKE_NONCOPYABLE(Observer);
+            protected:
+                Observer() {}
+            public:
+                virtual ~Observer() {}
+        
+                /**
+                 * Called when a provider signals an event has occured.
+                 * The provider is already locked. 
+                 * 
+                 * @param provider the provider being observed
+                 */
+                virtual void onEvent(MetadataProvider& provider)=0;
+            };
+            
+            /**
+             * Adds a metadata observer.
+             * 
+             * @param newObserver metadata observer to add
+             */
+            virtual void addObserver(Observer* newObserver) {
+                m_observers.push_back(newObserver);
+            }
+
+            /**
+             * Removes a metadata observer. The caller must delete the observer if necessary.
+             * 
+             * @param oldObserver metadata observer to remove
+             * @return  the old observer
+             */
+            virtual Observer* removeObserver(Observer* oldObserver) {
+                for (std::vector<Observer*>::iterator i=m_observers.begin(); i!=m_observers.end(); i++) {
+                    if (oldObserver==(*i)) {
+                        m_observers.erase(i);
+                        return oldObserver;
+                    }
+                }
+                return NULL;
+            }
+
+        private:
+            std::vector<Observer*> m_observers;
+        };
+    };
+};
+
+#endif /* __saml2_obsmetadataprov_h__ */
index 51c2b83..6b5a256 100644 (file)
@@ -21,7 +21,7 @@
  */
 
 #include "internal.h"
-#include "saml2/metadata/MetadataProvider.h"
+#include "saml2/metadata/ObservableMetadataProvider.h"
 
 #include <ctime>
 #include <sys/types.h>
@@ -41,7 +41,7 @@ namespace opensaml {
     namespace saml2md {
         
         
-        class SAML_DLLLOCAL FilesystemMetadataProvider : public MetadataProvider
+        class SAML_DLLLOCAL FilesystemMetadataProvider : public ObservableMetadataProvider
         {
         public:
             FilesystemMetadataProvider(const DOMElement* e);
@@ -88,7 +88,7 @@ static const XMLCh filename[] = UNICODE_LITERAL_8(f,i,l,e,n,a,m,e);
 static const XMLCh validate[] = UNICODE_LITERAL_8(v,a,l,i,d,a,t,e);
 
 FilesystemMetadataProvider::FilesystemMetadataProvider(const DOMElement* e)
-    : MetadataProvider(e), m_root(e), m_filestamp(0), m_validate(false), m_lock(NULL), m_object(NULL)
+    : ObservableMetadataProvider(e), m_root(e), m_filestamp(0), m_validate(false), m_lock(NULL), m_object(NULL)
 {
 #ifdef _DEBUG
     NDC ndc("FilesystemMetadataProvider");
@@ -234,6 +234,7 @@ Lockable* FilesystemMetadataProvider::lock()
                     delete m_object;
                     m_object = newstuff;
                     index();
+                    emitChangeEvent();
                 }
                 catch(XMLToolingException& e) {
                     Category::getInstance(SAML_LOGCAT".Metadata").error("failed to reload metadata from file, sticking with what we have: %s", e.what());
@@ -250,6 +251,7 @@ Lockable* FilesystemMetadataProvider::lock()
 
 void FilesystemMetadataProvider::index()
 {
+    clearDescriptorIndex();
     EntitiesDescriptor* group=dynamic_cast<EntitiesDescriptor*>(m_object);
     if (group) {
         MetadataProvider::index(group, SAMLTIME_MAX);
index 2a7052e..049cb6b 100644 (file)
@@ -191,7 +191,7 @@ void MetadataProvider::index(EntitiesDescriptor* group, time_t validUntil)
         index(*j,group->getValidUntilEpoch());
 }
 
-void MetadataProvider::clearIndex()
+void MetadataProvider::clearDescriptorIndex()
 {
     m_sources.clear();
     m_sites.clear();
diff --git a/saml/saml2/metadata/impl/ObservableMetadataProvider.cpp b/saml/saml2/metadata/impl/ObservableMetadataProvider.cpp
new file mode 100644 (file)
index 0000000..569c030
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  Copyright 2001-2006 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * ObservableMetadataProvider.cpp
+ * 
+ * A metadata provider that notifies interested parties of changes.
+ */
+
+#include "internal.h"
+#include "saml2/metadata/ObservableMetadataProvider.h"
+
+using namespace opensaml::saml2md;
+using namespace std;
+
+ObservableMetadataProvider::~ObservableMetadataProvider()
+{
+    for_each(m_observers.begin(),m_observers.end(),xmltooling::cleanup<Observer>());
+}
+
+void ObservableMetadataProvider::emitChangeEvent()
+{
+    for (std::vector<Observer*>::const_iterator i=m_observers.begin(); i!=m_observers.end(); i++) {
+        (*i)->onEvent(*this);
+    }
+}