text: # Minim_graph.py
  
  """
  Module to create RDF Minim graph throughn simple set of API calls
  """
  
  __author__      = "Graham Klyne (GK@ACM.ORG)"
  __copyright__   = "Copyright 2011-2013, University of Oxford"
  __license__     = "MIT (http://opensource.org/licenses/MIT)"
  
  import rdflib
  
  from rocommand.ro_namespaces import RDF
  
  from iaeval.ro_minim import MINIM
  
  class Minim_graph(object):
      """
      Class to create abstraction for constructing a Minim graph.
  
      The actual format of the resulting graph is implementation-dependent.
      This implementation builds an RDG graph, and serializes it in one of 
      a number of formats.  The default format is Turtle/N3.
      """
  
      def __init__(self, base=None):
          self._base    = base
          self._minimgr = rdflib.Graph()
          return
  
      def prefix(self, prefix, nsuri):
          self._minimgr.bind(prefix, rdflib.Namespace(nsuri))
          return
  
      def checklist(self, purpose=None, model=None, target="{+targetro}"):
          cls = rdflib.URIRef("#ChecklistConstraints", base=self._base)
          cln = rdflib.BNode()
          clt = rdflib.Literal(target)
          clp = rdflib.Literal(purpose)
          clm = rdflib.URIRef(model, base=self._base)
          self._minimgr.add( (cls, MINIM.hasChecklist, cln) )
          self._minimgr.add( (cln, RDF.type,                MINIM.Checklist) )
          self._minimgr.add( (cln, MINIM.forTargetTemplate, clt) )
          self._minimgr.add( (cln, MINIM.forPurpose,        clp) )
          self._minimgr.add( (cln, MINIM.toModel,           clm) )
          return cln
  
      def model(self, modelid, itemlist):
          model = rdflib.URIRef(modelid, base=self._base)
          self._minimgr.add( (model, RDF.type, MINIM.Model) )
          for (level, item) in itemlist:
              self._minimgr.add( (model, level, item) )
          return model
  
      def item(self, seq=None, level="MUST", ruleid=None):
          item = rdflib.BNode()
          rule = rdflib.URIRef(ruleid, base=self._base)
          self._minimgr.add( (item, RDF.type, MINIM.Requirement) )
          self._minimgr.add( (item, MINIM.isDerivedBy, rule) )
          if seq:
              self._minimgr.add( (item, MINIM.seq, rdflib.Literal(seq)) )
          levelmap = (
              { "MUST":   MINIM.hasMustRequirement
              , "SHOULD": MINIM.hasShouldRequirement
              , "MAY":    MINIM.hasMayRequirement
              })
          return (levelmap[level], item)
  
      def rule(self,
               ruleid, ForEach=None, ResultMod=None, Exists=None, Min=0, Max=None, 
               Aggregates=None, IsLive=None, 
               Command=None, Response=None,
               Show=None, Pass="None", Fail="None", NoMatch="None"):
          rule = rdflib.URIRef(ruleid, base=self._base)
          if ForEach:
              ruletype  = MINIM.QueryTestRule
              querynode = rdflib.BNode()
              self._minimgr.add( (rule, MINIM.query, querynode) )
              self._minimgr.add( (querynode, MINIM.sparql_query, rdflib.Literal(ForEach)) )
              if ResultMod:
                  self._minimgr.add( (querynode, MINIM.result_mod, rdflib.Literal(ResultMod)) )
              if Exists:
                  existsnode = rdflib.BNode()
                  self._minimgr.add( (rule, MINIM.exists, existsnode) )
                  self._minimgr.add( (existsnode, MINIM.sparql_query, rdflib.Literal(Exists)) )
              if Min:
                  self._minimgr.add( (rule, MINIM.min, rdflib.Literal(Min)) )
              if Max:
                  self._minimgr.add( (rule, MINIM.max, rdflib.Literal(Max)) )
              if Aggregates:
                  self._minimgr.add( (rule, MINIM.aggregatesTemplate, rdflib.Literal(Aggregates)) )
              if IsLive:
                  self._minimgr.add( (rule, MINIM.isLiveTemplate, rdflib.Literal(IsLive)) )
          elif Exists:
              ruletype = MINIM.QueryTestRule
              existsnode = rdflib.BNode()
              self._minimgr.add( (rule, MINIM.exists, existsnode) )
              self._minimgr.add( (existsnode, MINIM.sparql_query, rdflib.Literal(Exists)) )
          elif Command:
              ruletype = MINIM.SoftwareEnvironmentRule
              self._minimgr.add( (rule, MINIM.command, rdflib.Literal(Command)) )
              self._minimgr.add( (rule, MINIM.response, rdflib.Literal(Response)) )
          else:
              raise ValueError("Unrecognized requirement rule pattern")
          self._minimgr.add( (rule, RDF.type, ruletype) )
          if Show:
              self._minimgr.add( (rule, MINIM.show,     rdflib.Literal(Show)) )
          if Pass:
              self._minimgr.add( (rule, MINIM.showpass, rdflib.Literal(Pass)) )
          if Fail:
              self._minimgr.add( (rule, MINIM.showfail, rdflib.Literal(Fail)) )
          if NoMatch:
              self._minimgr.add( (rule, MINIM.showmiss, rdflib.Literal(NoMatch)) )
          return rule
  
      def collectlist(self, rule, listprop, listvars):
          for c in listvars:
              listnode = rdflib.BNode()
              self._minimgr.add( (rule, listprop,  listnode) )
              self._minimgr.add( (listnode, RDF.type, MINIM.ValueCollector) )
              # Note: strips off leading '?' from variable names
              self._minimgr.add( (listnode, MINIM.collectVar,  rdflib.Literal(c["collectvar"][1:])) )
              self._minimgr.add( (listnode, MINIM.collectList, rdflib.Literal(c["collectlist"][1:])) )
          return
  
      def serialize(self, outstr, format="turtle"):
          self._minimgr.serialize(destination=outstr, format=format)
          return
  
      def graph(self):
          return self._minimgr
  
  # End.
  