Fawkes API  Fawkes Development Version
url_manager.cpp
00001 
00002 /***************************************************************************
00003  *  url_manager.cpp - Web URL manager
00004  *
00005  *  Created: Thu Nov 25 21:56:19 2010
00006  *  Copyright  2006-2010  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022 
00023 #include <webview/url_manager.h>
00024 #include <webview/request_processor.h>
00025 #include <core/threading/mutex.h>
00026 #include <core/threading/mutex_locker.h>
00027 #include <core/exception.h>
00028 
00029 namespace fawkes {
00030 #if 0 /* just to make Emacs auto-indent happy */
00031 }
00032 #endif
00033 
00034 
00035 /** @class WebUrlManager <webview/url_manager.h>
00036  * Manage URL mappings.
00037  * This class maps (base) URLs to web request processors which handle all
00038  * requests for the given URL.
00039  * @author Tim Niemueller
00040  */
00041 
00042 /** Constructor. */
00043 WebUrlManager::WebUrlManager()
00044 {
00045   __mutex = new Mutex();
00046   __startpage_processor = NULL;
00047 }
00048 
00049 
00050 /** Destructor. */
00051 WebUrlManager::~WebUrlManager()
00052 {
00053   delete __mutex;
00054 }
00055 
00056 
00057 /** Add a request processor.
00058  * @param url_prefix baseurl this processor should handle
00059  * @param processor processor for baseurl
00060  * @exception Exception thrown if a processor has already been registered
00061  * for the given URL prefix.
00062  */
00063 void
00064 WebUrlManager::register_baseurl(const char *url_prefix,
00065                                 WebRequestProcessor *processor)
00066 {
00067   MutexLocker lock(__mutex);
00068   if (std::string(url_prefix) == "/") {
00069     if (__startpage_processor) {
00070       throw Exception("Start page processor has already been registered");
00071     }
00072     __startpage_processor = processor;
00073   } else {
00074     if (__processors.find(url_prefix) != __processors.end()) {
00075       throw Exception("A processor for %s has already been registered",
00076                       url_prefix);
00077     }
00078     __processors[url_prefix] = processor;
00079   }
00080 }
00081 
00082 
00083 /** Remove a request processor.
00084  * @param url_prefix baseurl the processor handled
00085  */
00086 void
00087 WebUrlManager::unregister_baseurl(const char *url_prefix)
00088 {
00089   MutexLocker lock(__mutex);
00090   if (std::string(url_prefix) == "/") {
00091     __startpage_processor = NULL;
00092   } else {
00093     __processors.erase(url_prefix);
00094   }
00095 }
00096 
00097 /** Lock mutex and find processor.
00098  * This method determines if a processor has been registered for the URL.
00099  * It is the callers duty to ensure that the mutex has been locked while
00100  * searching and while using the found processor.
00101  * @param url url to get the processor for
00102  * @return request processor if found, NULL otherwise
00103  */
00104 WebRequestProcessor *
00105 WebUrlManager::find_processor(std::string &url) const
00106 {
00107   if ( url == "/" && __startpage_processor ) {
00108     return __startpage_processor;
00109   }
00110 
00111   WebRequestProcessor *proc = NULL;
00112   std::map<std::string, WebRequestProcessor *>::const_iterator pit;
00113   for (pit = __processors.begin();
00114        (proc == NULL) && (pit != __processors.end());
00115        ++pit)
00116   {
00117     if (url.find(pit->first) == 0) {
00118       url = pit->first;
00119       return pit->second;
00120     }
00121   }
00122 
00123   return NULL;
00124 }
00125 
00126 
00127 /** Get internal mutex.
00128  * Use this mutex to guard find_processor() and a following invocation of
00129  * a found processor against changes due to registering/unregistering of
00130  * processors.
00131  * @return internal mutex
00132  */
00133 Mutex *
00134 WebUrlManager::mutex()
00135 {
00136   return __mutex;
00137 }
00138 
00139 } // end namespace fawkes