CORD-1386: Port existing code to new data validation strategy

Change-Id: Id50d8cf76afa9f6cc7752b0d3cc451492a0a66f3
diff --git a/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py b/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py
index 336373f..ca39b17 100644
--- a/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py
+++ b/lib/xos-genx/xosgenx/jinja2_extensions/fol2.py
@@ -207,7 +207,7 @@
         self.verdict_next()
         function_str = """
 def %(fn_name)s(obj, ctx):
-    if not %(vvar)s: raise ValidationError("%(message)s")
+    if not %(vvar)s: raise ValidationError("%(message)s".format(obj=obj, ctx=ctx))
         """ % {'fn_name': policy_function_name, 'vvar': self.verdict_variable, 'message': message}
 
         function_ast = self.str_to_ast(function_str)
@@ -367,7 +367,7 @@
                 entry = f.pop()
 
                 python_str = """
-%(verdict_var)s = %(model)s.objects.filter(%(query)s)[0]
+%(verdict_var)s = not not %(model)s.objects.filter(%(query)s)
                 """ % {'verdict_var': verdict_var, 'model': var, 'query': entry}
 
                 python_ast = ast.parse(python_str)
@@ -393,7 +393,7 @@
                 vvar = self.verdict_variable
 
                 python_str = """
-%(verdict_var)s = %(model)s.objects.filter(%(query)s)[0]
+%(verdict_var)s = not not %(model)s.objects.filter(%(query)s)
                 """ % {'verdict_var': vvar, 'model': var, 'query': entry}
 
                 python_ast = ast.parse(python_str)
diff --git a/lib/xos-genx/xosgenx/targets/django-split.xtarget b/lib/xos-genx/xosgenx/targets/django-split.xtarget
index 8a0082a..a6ccab5 100644
--- a/lib/xos-genx/xosgenx/targets/django-split.xtarget
+++ b/lib/xos-genx/xosgenx/targets/django-split.xtarget
@@ -14,6 +14,9 @@
 {% endif %}
 {% endfor %}
 
+{% for policy,error in xproto_validations(m.options) %}
+{{ xproto_fol_to_python_validator(policy, proto.policies[policy], m, error) }}
+{% endfor %}
 
 class {{ m.name }}{{ xproto_base_def(m.name, m.bases) }}:
   plural_name = "{{ xproto_pluralize(m) }}"
@@ -37,8 +40,22 @@
       unique_together = {{ xproto_tuplify(uniques) }}
   {%- endif %}
   {% if file_exists(m.name|lower + '_model.py') -%}{{ include_file(m.name|lower + '_model.py') | indent(width=2)}}{%- endif %}
-  pass
 
+  {% if m.name!='XOSBase' and 'Mixin' not in m.name %}
+
+  # Generated methods
+  def save(self, *args, **kwds):
+      try:
+          self.__xos_save_base(*args, **kwds)
+      except AttributeError:
+          pass
+
+      {% for policy,error in xproto_validations(m.options) %}
+      policy_{{policy}}_validator(self, None)
+      {% endfor %}
+      super({{ m.name }}, self).save(*args, **kwds)
+
+  {% endif %}
 {% if file_exists(xproto_base_name(m.name)|lower+'_bottom.py') -%}{{ include_file(xproto_base_name(m.name)|lower+'_bottom.py') }}{% endif %}
 +++ {{m.name|lower}}.py
 {% endif %}{% endfor %}
diff --git a/lib/xos-genx/xosgenx/targets/django.xtarget b/lib/xos-genx/xosgenx/targets/django.xtarget
index 67e25c5..400596c 100644
--- a/lib/xos-genx/xosgenx/targets/django.xtarget
+++ b/lib/xos-genx/xosgenx/targets/django.xtarget
@@ -1,11 +1,10 @@
 {% for m in proto.messages %}{% if not m.options.skip_django -%}
 {% if file_exists(xproto_base_name(m.name)|lower+'_header.py') -%}from {{xproto_base_name(m.name)|lower }}_header import *{%- else -%}from header import *{% endif %}
 {% if file_exists(xproto_base_name(m.name)|lower+'_top.py') -%}{{ include_file(xproto_base_name(m.name)|lower+'_top.py') }} {% endif %}
-
 {%- for l in m.links %}
 
 {% if l.peer.name != m.name %}
-from core.models.{{ l.peer.name | lower }} import {{ l.peer.name }}
+from core.models.{{ l.peer.name | lower }} import {{ l.peer.name }} 
 {% endif %}
 
 {%- endfor %}
@@ -15,6 +14,9 @@
 {% endif %}
 {% endfor %}
 
+{% for policy,error in xproto_validations(m.options) %}
+{{ xproto_fol_to_python_validator(policy, proto.policies[policy], m, error) }}
+{% endfor %}
 
 class {{ m.name }}{{ xproto_base_def(m.name, m.bases) }}:
   plural_name = "{{ xproto_pluralize(m) }}"
@@ -40,5 +42,19 @@
   {% if file_exists(m.name|lower + '_model.py') -%}{{ include_file(m.name|lower + '_model.py') | indent(width=2)}}{%- endif %}
   pass
 
+  {% if m.name!='XOSBase' and 'Mixin' not in m.name %}
+  # Generated methods
+  def save(self, *args, **kwds):
+      try:
+          self.__xos_save_base(*args, **kwds)
+      except AttributeError:
+          pass
+
+      {% for policy,error in xproto_validations(m.options) %}
+      policy_{{policy}}_validator(self, None)
+      {% endfor %}
+      super({{ m.name }}, self).save(*args, **kwds)
+  {% endif %}
+    
 {% if file_exists(xproto_base_name(m.name)|lower+'_bottom.py') -%}{{ include_file(xproto_base_name(m.name)|lower+'_bottom.py') }}{% endif %}
 {% endif %}{% endfor %}
diff --git a/lib/xos-genx/xosgenx/targets/service.xtarget b/lib/xos-genx/xosgenx/targets/service.xtarget
index e70f0d6..a48abb7 100644
--- a/lib/xos-genx/xosgenx/targets/service.xtarget
+++ b/lib/xos-genx/xosgenx/targets/service.xtarget
@@ -26,6 +26,10 @@
 {%- endif -%}
 {% endfor %}
 
+{% for policy,error in xproto_validations(m.options) %}
+{{ xproto_fol_to_python_validator(policy, proto.policies[policy], m, error) }}
+{% endfor %}
+
 {% endfor %}
 
 {% for m in proto.messages %}
@@ -55,6 +59,18 @@
   {% if file_exists(m.name|lower + '_model.py') -%}{{ include_file(m.name|lower + '_model.py') | indent(width=2)}}{%- endif %}
   pass
 
+  # Generated methods
+  def save(self, *args, **kwds):
+      try:
+          self.__xos_save_base(*args, **kwds)
+      except AttributeError:
+          pass
+
+      {% for policy,error in xproto_validations(m.options) %}
+      policy_{{policy}}_validator(self, None)
+      {% endfor %}
+      super({{ m.name }}{{ legacy_tag }}, self).save(*args, **kwds)
+
 {% if file_exists(m.name|lower+'_bottom.py') -%}{{ include_file(m.name|lower+'_bottom.py') }}{% endif %} 
 {% endfor %}
 +++ models{{ legacy_tag }}.py