########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Server/Client/Commands/Rdf/Complete.py,v 1.18 2004/10/16 05:32:55 mbrown Exp $
"""
Implementation of '4ss rdf complete' command
(functions defined here are used by the Ft.Lib.CommandLine framework)

Copyright 2004 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

__doc__ = """This command performs an RDF "complete": a query that \
returns, by default, all RDF statements from the combined system and \
user models in a 4Suite repository. The query can be constrained to \
return only those statements with a certain subject, predicate, object,
scope, or statement URI, in any combination. If necessary, you will be \
prompted first for credentials and access info to connect to the \
repository."""

import sys

from Ft.Server.Client.Commands import CommandUtil
from Ft.Server.Common import Util


def Run(options, args):
    ns_map = None
    repo = CommandUtil.GetRepository(options,'4ss.rdf.complete')
    if repo is not None:
        try:
            model = repo.getModel()
            res = model.complete(options.get('subject'),
                                 options.get('predicate'),
                                 options.get('object'),
                                 statementUri = options.get('uri'),
                                 scope = options.get('scope'))
            ns_map = Util.GetUserNsMappings(repo) #This is only needed for --xml
        finally:
            try:
                repo.txRollback()
            except:
                pass

    if repo is not None:
        if options.get('xml'):
            #This get rather convoluted
            from Ft.Rdf.Drivers import Memory
            from Ft.Rdf import Model
            from Ft.Rdf.Serializers import Dom
            from Ft.Xml.Domlette import PrettyPrint
            mem = Memory.DbAdapter('')
            mem.begin()
            mod = Model.Model(mem)
            mod.add(res)
            ser = Dom.Serializer()
            res = ser.serialize(mod, nsMap=ns_map)
            PrettyPrint(res)
        elif options.get('flat-model'):
            CommandUtil.WritePreamble('Statements:')
            for s in res:
                print s.subject, s.predicate, s.object, s.uri
        else:
            scopes = {}
            for s in res:
                if not scopes.has_key(s.scope):
                    scopes[s.scope] = []
                scopes[s.scope].append(s)
            for k, v in scopes.items():
                heading = 'Scope: %s' % k
                CommandUtil.WritePreamble(heading, stream=sys.stdout)
                for s in v:
                    print (u'%s %s %s%s%s' % (s.subject, s.predicate,
                                              Display(s.object, OBJ_LEN),
                                              ' ' * (not not s.uri),
                                              s.uri)).encode('utf-8')
                print
    return


OBJ_LEN = 50
def Display(text, length):
    if len(text) > length:
        result = text[:length] + '...'
    else:
        # why not just result=text?
        result = text[:length]
    result = result.replace("\n", "\\n")
    result = result.replace("\r", "\\r")
    return result


def Register():

    from Ft.Lib.CommandLine import Options, Command, Arguments

    cmd = Command.Command('complete',
                          'Perform an RDF complete',
                          '--subject=urn:uuid1234456',
                          __doc__,
                          function = Run,
                          arguments = [
                                       ],
                          options = Options.Options([Options.Option(None,'subject=','The subject for the complete'),
                                                     Options.Option(None,'predicate=','The predicate for the complete'),
                                                     Options.Option(None,'object=','The object for the complete'),
                                                     Options.Option(None,'uri=URI','The URI of the statement to fetch'),
                                                     Options.Option(None,'scope=','The scope of statements to fetch'),
                                                     Options.Option('x', 'xml', 'Generate Serialized RDF in XML format'),
                                                     Options.Option(None, 'flat-model', 'Do not show the results sorted by scope'),
                                      ]),
                          fileName = __file__,
                          )
    return cmd


