########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Server/Client/Commands/Rdf/Add.py,v 1.13 2004/09/23 20:53:30 mbrown Exp $
"""
Implementation of '4ss rdf add' 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__ = """Adds statements to the user RDF model associated with a \
4Suite repository. A single statement can be given via command-line \
arguments, or multiple statements can be given in an RDF XML file that \
will be deserialized. If necessary, you will be prompted first for \
credentials and access info to connect to the repository."""

import sys

from Ft.Lib import Uri
from Ft.Lib.CommandLine.CommandLineUtil import SourceArgToInputSource
from Ft.Rdf import OBJECT_TYPE_LITERAL, OBJECT_TYPE_UNKNOWN
from Ft.Rdf.Statement import Statement
from Ft.Server.Client import FtServerClientException
from Ft.Server.Client.Commands import CommandUtil

OTYPES = {'literal': OBJECT_TYPE_LITERAL,
          'resource': OBJECT_TYPE_UNKNOWN,
          }


def Run(options,args):
    repo = CommandUtil.GetRepository(options, '4ss.rdf.add')
    if repo is not None:
        commit = False
        scope = args.get('scope')
        document = options.get('document')
        try:
            if document is not None:
                try:
                    source_isrc = SourceArgToInputSource(document, DefaultFactory)
                except ValueError, e:
                    sys.stderr.write(str(e)+'\n')
                    sys.stderr.flush()
                    return
                doc = repo.fetchResource(scope)
                content = doc_isrc.read()
                doc.deserializeAndAdd(content)
                commit = True
                doc_isrc.close()
            else:
                model = repo.getModel()
                subj = args.get('subject')
                pred = args.get('predicate')
                obj = args.get('object')
                uri = args.get('uri')
                objtype = options.get('objtype', OBJECT_TYPE_LITERAL)
                s = Statement(subj, pred, obj, statementUri=uri, scope=scope, objectType=objtype)
                if scope and options.get('create'):
                    #Create an empty RDF doc
                    doc = repo.createDocument(
                        scope, '<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"/>',
                        imt=options.get('imt', 'text/xml'),
                        forcedType=ResourceTypes.ResourceType.RDF_DOCUMENT,
                    )
                model.add([s])
            commit = True
        finally:
            try:
                if commit:
                    repo.txCommit()
                else:
                    repo.txRollback()
            except:
                pass
    return


def Register():

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

    cmd = Command.Command('add',
                          'Add RDF statements to a given scope',
                          '--document=spam.rdf /my/scope/path',
                          __doc__,
                          function = Run,
                          arguments = [Arguments.RequiredArgument('scope',
                                                                  "The scope into which the statements are to be added",
                                                                  str),
                                       Arguments.OptionalArgument('subject',
                                                                  "The subject of the new statement",
                                                                  str),
                                       Arguments.OptionalArgument('predicate',
                                                                  "The predicate of the new statement",
                                                                  str),
                                       Arguments.OptionalArgument('object',
                                                                  "The object of the new statement",
                                                                  str),
                                       Arguments.OptionalArgument('uri',
                                                                  "The URI of the new statement.",
                                                                  str),
                                      ],
                          options = Options.Options([Options.Option('d', 'document=URI', 'Add statements deserialized from the given document'),
                                                     Options.Option(None, 'create', "When adding a single statement, create a virtual RDF document representing the scope, if it doesn't already exist"),
                                                     Options.Option(None, 'imt', "When creating a virtual RDF document, the Internet Media Type (default: text/xml) to set"),
                                                     Options.Option(None, 'objtype=TYPE', "When adding a single statement, the type of the object, either 'resource' or 'literal' (default: literal)"),
                                      ]),
                          fileName = __file__,
                          )
    return cmd

