Merge branch 'master' of ssh://git.onelab.eu/git/sfa
[sfa.git] / sfa / rspecs / version_manager.py
1 import os
2 from sfa.util.faults import InvalidRSpec, UnsupportedRSpecVersion
3 from sfa.rspecs.version import RSpecVersion 
4 from sfa.util.sfalogging import logger    
5
6 class VersionManager:
7     def __init__(self):
8         self.versions = []
9         self.load_versions()
10
11     def load_versions(self):
12         path = os.path.dirname(os.path.abspath( __file__ ))
13         versions_path = path + os.sep + 'versions'
14         versions_module_path = 'sfa.rspecs.versions'
15         valid_module = lambda x: os.path.isfile(os.sep.join([versions_path, x])) \
16                         and x.endswith('.py') and x !=  '__init__.py'
17         files = [f for f in os.listdir(versions_path) if valid_module(f)]
18         for filename in files:
19             basename = filename.split('.')[0]
20             module_path = versions_module_path +'.'+basename
21             module = __import__(module_path, fromlist=module_path)
22             for attr_name in dir(module):
23                 attr = getattr(module, attr_name)
24                 if hasattr(attr, 'version') and hasattr(attr, 'enabled') and attr.enabled == True:
25                     self.versions.append(attr())
26
27     def _get_version(self, type, version_num=None, content_type=None):
28         retval = None
29         for version in self.versions:
30             if type is None or type.lower() == version.type.lower():
31                 if version_num is None or str(version_num) == version.version:
32                     if content_type is None or content_type.lower() == version.content_type.lower() \
33                       or version.content_type == '*':
34                         retval = version
35                         ### sounds like we should be glad with the first match, not the last one
36                         break
37         if not retval:
38             raise UnsupportedRSpecVersion("[%s %s %s] is not suported here"% (type, version_num, content_type))
39         return retval
40
41     def get_version(self, version=None):
42         retval = None
43         if isinstance(version, dict):
44             retval =  self._get_version(version.get('type'), version.get('version'), version.get('content_type'))
45         elif isinstance(version, basestring):
46             version_parts = version.split(' ')     
47             num_parts = len(version_parts)
48             type = version_parts[0]
49             version_num = None
50             content_type = None
51             if num_parts > 1:
52                 version_num = version_parts[1]
53             if num_parts > 2:
54                 content_type = version_parts[2]
55             retval = self._get_version(type, version_num, content_type) 
56         elif isinstance(version, RSpecVersion):
57             retval = version
58         else:
59             raise UnsupportedRSpecVersion("No such version: %s "% str(version))
60  
61         return retval
62
63     def get_version_by_schema(self, schema):
64         retval = None
65         for version in self.versions:
66             if schema == version.schema:
67                 retval = version
68         if not retval:
69             raise InvalidRSpec("Unkwnown RSpec schema: %s" % schema)
70         return retval
71
72 def show_by_string(string):
73     try:
74         print v.get_version(string)
75     except Exception,e:
76         print e
77 def show_by_schema(string):
78     try:
79         print v.get_version_by_schema(string)
80     except Exception,e:
81         print e
82
83 if __name__ == '__main__':
84     v = VersionManager()
85     print v.versions
86     show_by_string('sfa 1') 
87     show_by_string('protogeni 2') 
88     show_by_string('protogeni 2 advertisement') 
89     show_by_schema('http://www.protogeni.net/resources/rspec/2/ad.xsd') 
90     show_by_schema('http://sorch.netmode.ntua.gr/ws/RSpec/ad.xsd')
91