ModuleManager.py

説明を見る。
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 ##
00005 # @file ModuleManager.py
00006 # @brief Loadable modules manager class
00007 # @date $Date: 2007/08/24$
00008 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00009 #
00010 # Copyright (C) 2006-2008
00011 #     Task-intelligence Research Group,
00012 #     Intelligent Systems Research Institute,
00013 #     National Institute of
00014 #         Advanced Industrial Science and Technology (AIST), Japan
00015 #     All rights reserved.
00016 
00017 
00018 import string
00019 import os
00020 
00021 import OpenRTM
00022 
00023 
00024 CONFIG_EXT    = "manager.modules.config_ext"
00025 CONFIG_PATH   = "manager.modules.config_path"
00026 DETECT_MOD    = "manager.modules.detect_loadable"
00027 MOD_LOADPTH   = "manager.modules.load_path"
00028 INITFUNC_SFX  = "manager.modules.init_func_suffix"
00029 INITFUNC_PFX  = "manager.modules.init_func_prefix"
00030 ALLOW_ABSPATH = "manager.modules.abs_path_allowed"
00031 ALLOW_URL     = "manager.modules.download_allowed"
00032 MOD_DWNDIR    = "manager.modules.download_dir"
00033 MOD_DELMOD    = "manager.modules.download_cleanup"
00034 MOD_PRELOAD   = "manager.modules.preload"
00035 
00036 
00037 
00038 ##
00039 # @if jp
00040 #
00041 # @brief モジュールマネージャクラス
00042 # @class ModuleManager
00043 #
00044 # モジュールのロード、アンロードなどを管理するクラス
00045 #
00046 # @since 0.4.0
00047 #
00048 # @else
00049 #
00050 # @biref ModuleManager class
00051 #
00052 # @endif
00053 class ModuleManager:
00054   """
00055   """
00056 
00057 
00058 
00059   ##
00060   # @if jp
00061   #
00062   # @brief コンストラクタ
00063   #
00064   # コンストラクタ。
00065   # 設定された Property オブジェクト内の情報を基に初期化を実行する。
00066   #
00067   # @param self
00068   # @param prop 初期化用プロパティ
00069   #
00070   # @else
00071   #
00072   # @brief constructor
00073   #
00074   # @endif
00075   def __init__(self, prop):
00076     self._properties = prop
00077 
00078     self._configPath = prop.getProperty(CONFIG_PATH).split(",")
00079     for i in range(len(self._configPath)):
00080       tmp = [self._configPath[i]]
00081       OpenRTM.eraseHeadBlank(tmp)
00082       self._configPath[i] = tmp[0]
00083 
00084     self._loadPath = prop.getProperty(MOD_LOADPTH).split(",")
00085     for i in range(len(self._loadPath)):
00086       tmp = [self._loadPath[i]]
00087       OpenRTM.eraseHeadBlank(tmp)
00088       self._loadPath[i] = tmp[0]
00089 
00090     self._absoluteAllowed = OpenRTM.toBool(prop.getProperty(ALLOW_ABSPATH),
00091                          "yes", "no", False)
00092 
00093     self._downloadAllowed = OpenRTM.toBool(prop.getProperty(ALLOW_URL),
00094                          "yes", "no", False)
00095 
00096     self._initFuncSuffix = prop.getProperty(INITFUNC_SFX)
00097     self._initFuncPrefix = prop.getProperty(INITFUNC_PFX)
00098     self._modules = {}
00099 
00100 
00101   ##
00102   # @if jp
00103   #
00104   # @brief デストラクタ(未実装)
00105   #
00106   # @param self
00107   #
00108   # @else
00109   #
00110   # @brief destructor
00111   #
00112   # @endif
00113   def __del__(self):
00114     #self.unloadAll()
00115     pass
00116 
00117 
00118   ##
00119   # @if jp
00120   # @class Error
00121   # @brief ファイル・オープン失敗例外処理用内部クラス
00122   # @else
00123   #
00124   # @endif
00125   class Error:
00126     def __init__(self, reason_):
00127       self.reason = reason_
00128 
00129 
00130 
00131   ##
00132   # @if jp
00133   # @class NotFound
00134   # @brief 未実装部,指定モジュール不明例外処理用内部クラス
00135   # @else
00136   #
00137   # @endif
00138   class NotFound:
00139     def __init__(self, name_):
00140       self.name = name_
00141 
00142 
00143 
00144   ##
00145   # @if jp
00146   # @class FileNotFound
00147   # @brief 指定ファイル不明例外処理用内部クラス
00148   # @else
00149   #
00150   # @endif
00151   class FileNotFound(NotFound):
00152     def __init__(self, name_):
00153       ModuleManager.NotFound.__init__(self, name_)
00154 
00155 
00156 
00157   ##
00158   # @if jp
00159   # @class ModuleNotFound
00160   # @brief 指定モジュール不明例外処理用内部クラス
00161   # @else
00162   #
00163   # @endif
00164   class ModuleNotFound(NotFound):
00165     def __init__(self, name_):
00166       ModuleManager.NotFound.__init__(self, name_)
00167 
00168 
00169 
00170   ##
00171   # @if jp
00172   # @class SymbolNotFound
00173   # @brief 指定シンボル不明例外処理用内部クラス
00174   # @else
00175   #
00176   # @endif
00177   class SymbolNotFound(NotFound):
00178     def __init__(self, name_):
00179       ModuleManager.NotFound.__init__(self, name_)
00180 
00181 
00182 
00183   ##
00184   # @if jp
00185   # @class NotAllowedOperation
00186   # @brief 指定操作禁止時例外処理用内部クラス
00187   # @else
00188   #
00189   # @endif
00190   class NotAllowedOperation(Error):
00191     def __init__(self, reason_):
00192       ModuleManager.Error.__init__(self, reason_)
00193       ModuleManager.Error.__init__(self, reason_)
00194 
00195 
00196 
00197   ##
00198   # @if jp
00199   # @class InvalidArguments
00200   # @brief 指定引数不正時例外処理用内部クラス
00201   # @else
00202   #
00203   # @endif
00204   class InvalidArguments(Error):
00205     def __init__(self, reason_):
00206       ModuleManager.Error.__init__(self, reason_)
00207 
00208 
00209 
00210   ##
00211   # @if jp
00212   # @class InvalidOperation
00213   # @brief 指定操作不正時例外処理用内部クラス
00214   # @else
00215   #
00216   # @endif
00217   class InvalidOperation(Error):
00218     def __init__(self, reason_):
00219       ModuleManager.Error.__init__(self, reason_)
00220 
00221 
00222 
00223   ##
00224   # @if jp
00225   #
00226   # @brief モジュールのロード、初期化
00227   #
00228   # 指定したファイルを共有ライブラリとしてロードするとともに、
00229   # 指定した初期化用オペレーションを実行する。
00230   # 
00231   # @param self
00232   # @param file_name ロード対象モジュール名
00233   # @param init_func 初期化処理用オペレーション(デフォルト値:None)
00234   #
00235   # @return 指定したロード対象モジュール名
00236   #
00237   # @else
00238   #
00239   # @brief Load module
00240   #
00241   #
00242   # @endif
00243   def load(self, file_name, init_func=None):
00244     if file_name == "":
00245       raise ModuleManager.InvalidArguments, "Invalid file name."
00246 
00247     if OpenRTM.isURL(file_name):
00248       if not self._downloadAllowed:
00249         raise ModuleManager.NotAllowedOperation, "Downloading module is not allowed."
00250       else:
00251         raise ModuleManager.NotFound, "Not implemented."
00252 
00253     if OpenRTM.isAbsolutePath(file_name):
00254       if not self._absoluteAllowed:
00255         raise ModuleManager.NotAllowedOperation, "Absolute path is not allowed"
00256       else:
00257         file_path = file_name
00258       
00259     else:
00260       file_path = self.findFile(file_name, self._loadPath)
00261 
00262     if file_path == "":
00263       raise ModuleManager.InvalidArguments, "Invalid file name."
00264 
00265     if not self.fileExist(file_path+".py"):
00266       raise ModuleManager.FileNotFound, file_path
00267 
00268     mo = __import__(str(file_path))
00269     self._modules[file_name] = self.DLL(mo)
00270 
00271     if init_func is None:
00272       return file_path
00273 
00274     if file_path == "":
00275       raise ModuleManager.InvalidOperation, "Invalid file name"
00276 
00277     try:
00278       self._modules[file_name].dll.__getattribute__(init_func)()
00279     except:
00280       print "Could't call init_func: ", init_func
00281 
00282 
00283   ##
00284   # @if jp
00285   # @brief モジュールのアンロード
00286   #
00287   # 指定したロード済みモジュールをクローズし、アンロードする。
00288   #
00289   # @param self
00290   # @param file_name アンロード対象モジュール名
00291   #
00292   # @else
00293   # @brief Unload module
00294   # @endif
00295   def unload(self, file_name):
00296     if not self._modules.has_key(file_name):
00297       raise ModuleManager.NotFound, file_name
00298 
00299     # self._modules[file_name].dll.close()
00300     del self._modules[file_name]
00301 
00302 
00303   ##
00304   # @if jp
00305   # @brief 全モジュールのアンロード
00306   #
00307   # 全てのロード済みモジュールをアンロードする。
00308   #
00309   # @param self
00310   #
00311   # @else
00312   # @brief Unload all modules
00313   # @endif
00314   def unloadAll(self):
00315     keys   = self._modules.keys()
00316     
00317     self._modules.clear()
00318 
00319 
00320   ##
00321   # @if jp
00322   # @brief モジュールのシンボルの参照
00323   #
00324   # モジュールのシンボルを取得する
00325   #
00326   # @param self
00327   # @param file_name 取得対象ファイル名
00328   # @param func_name 取得対象関数名
00329   #
00330   # @else
00331   # @brief Look up a named symbol in the module
00332   # @endif
00333   def symbol(self, file_name, func_name):
00334     if not self._modules.has_key(file_name):
00335       raise ModuleManager.ModuleNotFound, file_name
00336 
00337     func = self._modules[file_name].dll.symbol(func_name)
00338 
00339     if not func:
00340       raise ModuleManager.SymbolNotFound, func_name
00341 
00342     return func
00343 
00344 
00345   ##
00346   # @if jp
00347   # @brief モジュールロードパスを指定する
00348   # 
00349   # モジュールロード時に対象モジュールを検索するパスを指定する。
00350   #
00351   # @param self
00352   # @param load_path_list モジュール検索対象パスリスト
00353   #
00354   # @else
00355   # @brief Set default module load path
00356   # @endif
00357   def setLoadpath(self, load_path_list):
00358     self._loadPath = load_path_list
00359     return
00360 
00361 
00362   ##
00363   # @if jp
00364   # @brief モジュールロードパスを取得する
00365   # 
00366   # 設定されているモジュールを検索対象パスリストを取得する。
00367   #
00368   # @param self
00369   # 
00370   # @return load_path モジュール検索対象パスリスト
00371   #
00372   # @else
00373   # @brief Get default module load path
00374   # @endif
00375   def getLoadPath(self):
00376     return self._loadPath
00377 
00378 
00379   ##
00380   # @if jp
00381   # @brief モジュールロードパスを追加する
00382   # 
00383   # 指定されたパスリストを検索対象パスリストに追加する。
00384   #
00385   # @param self
00386   # @param load_path 追加モジュール検索対象パスリスト
00387   #
00388   # @else
00389   # @brief Add module load path
00390   # @endif
00391   def addLoadpath(self, load_path):
00392     for path in load_path:
00393       self._loadPath.append(path)
00394     return
00395 
00396 
00397   ##
00398   # @if jp
00399   # @brief ロード済みのモジュールリストを取得する
00400   #
00401   # 既にロード済みのモジュールリストを取得する。
00402   #
00403   # @param self
00404   #
00405   # @return ロード済みモジュールリスト
00406   #
00407   # @else
00408   # @brief Get loaded module names
00409   # @endif
00410   def getLoadedModules(self):
00411     modules = []
00412     keys = self._modules.keys()
00413     for mod_name in keys:
00414       modules.append(mod_name)
00415 
00416     return modules
00417 
00418 
00419   ##
00420   # @if jp
00421   # @brief ロード可能モジュールリストを取得する(未実装)
00422   #
00423   # ロード可能なモジュールのリストを取得する。
00424   #
00425   # @param self
00426   #
00427   # @return ロード可能モジュールリスト
00428   #
00429   # @else
00430   # @brief Get loadable module names
00431   # @endif
00432   def getLoadableModules(self):
00433     return []
00434 
00435 
00436   ##
00437   # @if jp
00438   # @brief モジュールの絶対パス指定許可
00439   #
00440   # ロード対象モジュールの絶対パス指定を許可するように設定する。
00441   #
00442   # @param self
00443   #
00444   # @else
00445   # @brief Allow absolute load path
00446   # @endif
00447   def allowAbsolutePath(self):
00448     self._absoluteAllowed = True
00449 
00450 
00451   ##
00452   # @if jp
00453   # @brief モジュールの絶対パス指定禁止
00454   #
00455   # ロード対象モジュールの絶対パス指定を禁止するように設定する。
00456   #
00457   # @param self
00458   #
00459   # @else
00460   # @brief Forbid absolute load path
00461   # @endif
00462   def disallowAbsolutePath(self):
00463     self._absoluteAllowed = False
00464 
00465 
00466   ##
00467   # @if jp
00468   # @brief モジュールのURL指定許可
00469   #
00470   # ロード対象モジュールのURL指定を許可する。
00471   # 本設定が許可されている場合、モジュールをダウンロードしてロードすることが
00472   # 許可される。
00473   #
00474   # @param self
00475   #
00476   # @else
00477   # @brief Allow module download
00478   # @endif
00479   def allowModuleDownload(self):
00480     self._downloadAllowed = True
00481 
00482 
00483   ##
00484   # @if jp
00485   # @brief モジュールのURL指定禁止
00486   #
00487   # ロード対象モジュールのURL指定を禁止する。
00488   #
00489   # @param self
00490   #
00491   # @else
00492   # @brief Forbid module download
00493   # @endif
00494   def disallowModuleDownload(self):
00495     self._downloadAllowed = False
00496 
00497 
00498   ##
00499   # @if jp
00500   # @brief LoadPath からのファイルの検索
00501   # 
00502   # 指定されたパス内に、指定されたファイルが存在するか確認する。
00503   #
00504   # @param self
00505   # @param fname 検索対象ファイル名
00506   # @param load_path 検索先パスリスト
00507   #
00508   # @return 検索されたファイル名
00509   #
00510   # @else
00511   # @brief Search file from load path
00512   # @endif
00513   def findFile(self, fname, load_path):
00514     file_name = fname
00515 
00516     if len(load_path) == 1:
00517       load_path.append(".")
00518     for path in load_path:
00519       f = str(path)+"/"+str(file_name)+".py"
00520       if self.fileExist(f):
00521         return fname
00522     return ""
00523 
00524 
00525   ##
00526   # @if jp
00527   # @brief ファイルが存在するかどうかのチェック
00528   #
00529   # 指定されたファイルが存在するか確認する。
00530   #
00531   # @param self
00532   # @param filename 存在確認対象ファイル名
00533   #
00534   # @return ファイル存在確認結果(ファイルあり:true,なし:false)
00535   #
00536   # @else
00537   # @brief Check file existance
00538   # @endif
00539   def fileExist(self, filename):
00540     try:
00541       infile = open(filename)
00542     except:
00543       return False
00544 
00545     infile.close()
00546     return True
00547 
00548 
00549   ##
00550   # @if jp
00551   # @brief 初期化関数シンボルを生成する
00552   #
00553   # 初期化関数の名称を組み立てる。
00554   #
00555   # @param self
00556   # @param file_path 初期化対象モジュール名称
00557   #
00558   # @return 初期化関数名称組み立て結果
00559   #
00560   # @else
00561   # @brief Create initialize function symbol
00562   # @endif
00563   def getInitFuncName(self, file_path):
00564     base_name = os.path.basename(file_path)
00565     return str(self._initFuncPrefix)+str(base_name)+str(self._initFuncSuffix)
00566 
00567 
00568 
00569   ##
00570   # @if jp
00571   # @class DLL
00572   # @brief モジュール保持用内部クラス
00573   # @else
00574   #
00575   # @endif
00576   class DLL:
00577     def __init__(self, dll):
00578       self.dll = dll

OpenRTMに対してMon Mar 17 15:11:05 2008に生成されました。  doxygen 1.5.4