Commit 898fda2b authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

[code gen] Extract an abstract CodeGenerator base class out of yams schema generator

and use it for uicfg generation.
parent 02b391f85326
......@@ -5,7 +5,6 @@
# XXX unsupported merge because of incompatible cardinality SEDAArchiveUnitRefId seda_archive_unit_ref_id_to SEDAArchiveUnit ? <SEDAArchiveUnitRefId seda_archive_unit_ref_id_to set(['SEDAArchiveUnit'])> ?*
# XXX unsupported merge because of incompatible cardinality SEDADataObjectVersion seda_data_object_version_to Concept ? <SEDADataObjectVersion seda_data_object_version_to set(['Concept'])> ?*
# XXX extending cards for <SEDAUri> set(['0..1'])
# coding: utf-8
# copyright 2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
......
......@@ -22,7 +22,7 @@ except ImportError:
from cubicweb import devtools # noqa
from cubes.seda.xsd2yams import xsy_mapping, CodeGenerator, XSDMMapping
from cubes.seda.xsd2yams import xsy_mapping, YamsSchemaGenerator, XSDMMapping
class CodeGenerationTC(unittest.TestCase):
......@@ -30,7 +30,7 @@ class CodeGenerationTC(unittest.TestCase):
def test_base(self):
mapping = xsy_mapping('DataObjectPackage')
stream = StringIO()
CodeGenerator().generate(mapping, stream)
YamsSchemaGenerator().generate(mapping, stream)
code = stream.getvalue()
# assert this is valid python
compile(code, '<generated schema>', mode='exec')
......
......@@ -21,8 +21,7 @@ used bits).
from cubicweb import neg_role
from xsd import un_camel_case
from xsd2yams import PY_HEADER, HAS_ANNOTATIONS, xsy_mapping
from xsd2yams import HAS_ANNOTATIONS, CodeGenerator
LEVEL_ETYPES = set(('SEDABinaryDataObjectType', 'SEDAPhysicalDataObjectType',
......@@ -44,7 +43,9 @@ RTYPES_IN_TAB = set((
))
class UICFGGenerator(object):
class UICFGGenerator(CodeGenerator):
"""UICFG rules generator"""
rtags_info = {
'autoform_section': {
'shortname': 'afs',
......@@ -63,10 +64,9 @@ class UICFGGenerator(object):
},
}
def generate(self, mapping, stream):
def _generate(self, mapping, stream):
self._processed = set()
stream.write(PY_HEADER)
stream.write('\nfrom cubicweb.web import formwidgets as fw\n')
stream.write('from cubicweb.web import formwidgets as fw\n')
stream.write('from cubicweb.web.views import uicfg\n\n')
# indexview_etype_section configuration
stream.write('ives = uicfg.indexview_etype_section\n')
......@@ -93,14 +93,6 @@ class UICFGGenerator(object):
stream.write("affk.set_fields_order('{0}', {1})\n".format(etype, attributes))
stream.write("pvds.set_fields_order('{0}', {1})\n".format(etype, attributes))
def _callback(self, prefix, mapping_element):
callback = '{0}_{1}'.format(prefix, un_camel_case(mapping_element.__class__.__name__))
try:
method = getattr(self, callback)
except AttributeError:
return ()
return method(mapping_element)
def etypes_for_e_type_mapping(self, mapping):
yield mapping.etype
......@@ -165,5 +157,4 @@ class Code(unicode):
if __name__ == '__main__':
import sys
UICFGGenerator().generate(xsy_mapping(), sys.stdout)
UICFGGenerator.main()
......@@ -34,6 +34,12 @@ CARD_TO_CARDS = {
}
def xsy_mapping(tagname='ArchiveTransfer'):
mapping = XSYMapping()
mapping.collect(XSDMMapping(tagname))
return mapping
def yams_cardinality(minimum, maximum):
if minimum == 0 and maximum == 1:
return '?'
......@@ -209,19 +215,60 @@ def _merge_mapping(ref_mapping, subjtype, rtype, objtype, composite, card=None):
# code generation ##################################################################################
class CodeGenerator(object):
"""Abstract class for code generator"""
@classmethod
def main(cls):
"""A main implementation to generate code"""
import sys
if len(sys.argv) < 2:
mapping = xsy_mapping()
else:
assert len(sys.argv) == 2
mapping = xsy_mapping(sys.argv[1])
cls().generate(mapping, sys.stdout)
def generate(self, xsy_mapping, outfile, with_header=True):
"""Generate a Yams schema (python code) for the given mapped XSD element in `outfile`
stream.
def generate(self, mapping, stream, with_header=True):
"""Generator entry point: write generated code for :class:`XSYMapping` into the given stream
"""
if with_header:
outfile.write(_YAMS_PY_HEADER)
stream.write(PY_HEADER)
self._generate(mapping, stream)
def _generate(self, mapping, stream):
"""Override me in concret class"""
raise NotImplementedError()
def _callback(self, prefix, mapping_element):
"""Call method named according to `prefix` and `mapping_element`'s class and return its
result or an empty tuple if the method doesn't exist
"""
callback = '{0}_{1}'.format(prefix, un_camel_case(mapping_element.__class__.__name__))
try:
method = getattr(self, callback)
except AttributeError:
return ()
return method(mapping_element)
class YamsSchemaGenerator(CodeGenerator):
"""Yams schema generator"""
def _generate(self, mapping, stream):
stream.write('''from yams.buildobjs import EntityType, RelationDefinition
from yams.buildobjs import String, Int, Boolean, Decimal, Date, TZDatetime
from cubicweb.schema import RQLConstraint
from cubes.seda.schema import seda_profile_element
_ = unicode
''')
self._processed_complex_rdef = set()
for mapping_element in xsy_mapping.ordered:
callback = 'code_for_{0}'.format(un_camel_case(mapping_element.__class__.__name__))
mapping_code = getattr(self, callback)(mapping_element)
outfile.write(mapping_code.encode('utf8'))
for mapping_element in mapping.ordered:
mapping_code = self._callback('code_for', mapping_element)
stream.write(mapping_code.encode('utf8'))
def code_for_e_type_mapping(self, mapping):
if mapping.cards:
......@@ -390,31 +437,9 @@ PY_HEADER = '''# copyright 2016 LOGILAB S.A. (Paris, FRANCE), all rights reserve
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""THIS FILE IS GENERATED FROM SEDA 2.0 XSD FILES, DO NOT EDIT"""
'''
_YAMS_PY_HEADER = '''# coding: utf-8
{0}
from yams.buildobjs import EntityType, RelationDefinition
from yams.buildobjs import String, Int, Boolean, Decimal, Date, TZDatetime
from cubicweb.schema import RQLConstraint
from cubes.seda.schema import seda_profile_element
_ = unicode
'''.format(PY_HEADER)
def xsy_mapping(tagname='ArchiveTransfer'):
mapping = XSYMapping()
mapping.collect(XSDMMapping(tagname))
return mapping
'''
if __name__ == '__main__':
import sys
if len(sys.argv) < 2:
mapping = xsy_mapping()
else:
assert len(sys.argv) == 2
mapping = xsy_mapping(sys.argv[1])
CodeGenerator().generate(mapping, sys.stdout)
YamsSchemaGenerator.main()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment