########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Server/Client/Commands/Rdf/Remove.py,v 1.14 2004/09/23 20:53:30 mbrown Exp $
"""
Implementation of '4ss rdf remove' 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 removes statements from the user RDF model \
in 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 Model
from Ft.Rdf.Statement import Statement
from Ft.Server.Client.Commands import CommandUtil
from Ft.Xml.InputSource import DefaultFactory


def Run(options, args):
    flags = {}
    if options.get('subject-regex'):
        flags['subjectFlags'] = Model.REGEX
    if options.get('predicate-regex'):
        flags['predicateFlags'] = Model.REGEX
    if options.get('object-regex'):
        flags['objectFlags'] = Model.REGEX

    repo = CommandUtil.GetRepository(options, '4ss.rdf.remove')
    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.deserializeAndRemove(content)
                commit = True
                doc_isrc.close()
            else:
                model = repo.getModel()
                subj = options.get('subject')
                pred = options.get('predicate')
                obj = options.get('object')
                #FIXME: make requirement that they must be superuser to
                #Remove a statement without specified scope
                apply(model.removePattern, (subj, pred, obj, None, scope), flags)
                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('remove',
                          'Remove RDF statements from a given scope',
                          '--document=spam.rdf /my/scope/path',
                          __doc__,
                          function = Run,
                          arguments = [Arguments.OptionalArgument('scope',
                                                                  "The scope from which the statements are to be removed",
                                                                  str)],
                          options = Options.Options([
                              Options.Option('d', 'document=', 'Remove statements deserialized from the given document'),
                              Options.Option(None, 'subject=', 'The subject of statements selected to be deleted'),
                              Options.Option(None, 'predicate=', 'The predicate of statements selected to be deleted'),
                              Options.Option(None, 'object=', 'The object of statements selected to be deleted'),
                              Options.Option(None, 'subject-regex', 'The subject string is a regular expression to match'),
                              Options.Option(None, 'predicate-regex', 'The predicate string is a regular expression to match'),
                              Options.Option(None, 'object-regex', 'The object string is a regular expression to match'),
                                      ]),
                          fileName = __file__,
                          )
    return cmd

