# This file is part of Pantry, command-line nutrient analysis.
# 
# Version 22, released Saturday, October 13, 2007.
# 
# Copyright 2007 Omari Norman.
# 
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated
# documentation files (the "Software"), to deal in the
# Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
# 
# The above copyright notice and this permission notice shall
# be included in all copies or substantial portions of the
# Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# 
# Pantry's "built-in" XML validator is a modified version of
# xmlproc.  xmlproc is Copyright 1998-2000 by Lars Marius
# Garshol, Oslo, Norway.
# 
# All Rights Reserved
# 
# Permission to use, copy, modify, and distribute this
# software and its documentation for any purpose and without
# fee is hereby granted, provided that the above copyright
# notice appear in all copies and that modified copies are
# clearly marked as such.
# 
# LARS MARIUS GARSHOL DISCLAIMS ALL WARRANTIES WITH REGARD TO
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL LARS MARIUS
# GARSHOL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
# USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

"""
Support for XCatalog catalog files.
$Id: xcatalog.py,v 1.9 2001/12/30 12:09:14 loewis Exp $
"""

import catalog,xmlapp,xmlproc

# --- An XCatalog parser factory

class XCatParserFactory:

    def __init__(self,error_lang=None):
        self.error_lang=error_lang

    def make_parser(self,sysid):
        return XCatalogParser(self.error_lang)

class FancyParserFactory:

    def __init__(self,error_lang=None):
        self.error_lang=error_lang

    def make_parser(self,sysid):
        if sysid[-4:]==".soc":
            return catalog.CatalogParser(self.error_lang)
        elif sysid[-4:]==".xml":
            return XCatalogParser(self.error_lang)
        else:
            return catalog.CatalogParser(self.error_lang)

# --- An XCatalog 0.1 parser

class XCatalogParser(catalog.AbstrCatalogParser,xmlapp.Application):

    def __init__(self,error_lang=None):
        catalog.AbstrCatalogParser.__init__(self)
        xmlapp.Application.__init__(self)
        self.error_lang=error_lang

    def parse_resource(self,sysid):
        parser=xmlproc.XMLProcessor()
        self.parser=parser
        parser.set_application(self)
        if self.error_lang!=None:
            parser.set_error_language(self.error_lang)
        parser.set_error_handler(self.err)
        parser.parse_resource(sysid)
        del self.parser

    def handle_start_tag(self,name,attrs):
        try:
            if name=="Base":
                self.app.handle_base(attrs["HRef"])
            elif name=="Map":
                self.app.handle_public(attrs["PublicID"],attrs["HRef"])
            elif name=="Delegate":
                self.app.handle_delegate(attrs["PublicID"],attrs["HRef"])
            elif name=="Extend":
                self.app.handle_catalog(attrs["HRef"])
            elif name!="XCatalog":
                self.parser.report_error(5000,(name,))
        except KeyError,e:
            if e.args[0] in ("HRef" , "PublicID"):
                self.parser.report_error(5001,(e.args[0],name))
            else:
                raise e # This came from the application, pass it on

    # implementing Locator methods

    def get_current_sysid(self):
        return self.parser.get_current_sysid()

    def get_line(self):
        return self.parser.get_line()

    def get_column(self):
        return self.parser.get_column()
