# *************************************************************
#
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.
#
# *************************************************************

# XScript implementation for python
import uno
import unohelper
import sys
import os
import types
import time
import ast
import re

try:
    unicode
except NameError:
    unicode = str

class LogLevel:
    NONE = 0   # production level
    ERROR = 1  # for script developers
    DEBUG = 2  # for script framework developers

PYSCRIPT_LOG_ENV = "PYSCRIPT_LOG_LEVEL"
PYSCRIPT_LOG_STDOUT_ENV = "PYSCRIPT_LOG_STDOUT"

# Configuration ----------------------------------------------------
LogLevel.use = LogLevel.NONE
if os.environ.get(PYSCRIPT_LOG_ENV) == "ERROR":
    LogLevel.use = LogLevel.ERROR
elif os.environ.get(PYSCRIPT_LOG_ENV) == "DEBUG":
    LogLevel.use = LogLevel.DEBUG

# True, writes to stdout (difficult on windows)
# False, writes to user/Scripts/python/log.txt
LOG_STDOUT = os.environ.get(PYSCRIPT_LOG_STDOUT_ENV, "1") != "0"

#-------------------------------------------------------------------

def encfile(uni):
    if sys.version_info[0] > 2:
        return uni
    else:
        return uni.encode( sys.getfilesystemencoding())

def lastException2String():
    (excType,excInstance,excTraceback) = sys.exc_info()
    ret = str(excType) + ": "+str(excInstance) + "\n" + \
          uno._uno_extract_printable_stacktrace( excTraceback )
    return ret

def logLevel2String( level ):
    ret = " NONE"
    if level == LogLevel.ERROR:
        ret = "ERROR"
    elif level >= LogLevel.DEBUG:
        ret = "DEBUG"
    return ret

def getLogTarget():
    ret = sys.stdout
    if not LOG_STDOUT:
        try:
            pathSubst = uno.getComponentContext().ServiceManager.createInstance(
                "com.sun.star.util.PathSubstitution" )
            userInstallation =  pathSubst.getSubstituteVariableValue( "user" )
            if len( userInstallation ) > 0:
                systemPath = uno.fileUrlToSystemPath( userInstallation + "/Scripts/python/log.txt" )
                ret = open( systemPath , "a" )
        except Exception as e:
            print("Exception during creation of pythonscript logfile: "+ lastException2String() + "\n, delagating log to stdout\n")
    return ret

class Logger(LogLevel):
    def __init__(self , target ):
        self.target = target

    def isDebugLevel( self ):
        return self.use >= self.DEBUG

    def debug( self, msg ):
        if self.isDebugLevel():
            self.log( self.DEBUG, msg )

    def isErrorLevel( self ):
        return self.use >= self.ERROR

    def error( self, msg ):
        if self.isErrorLevel():
            self.log( self.ERROR, msg )

    def log( self, level, msg ):
        if self.use >= level:
            try:
                self.target.write(
                    time.asctime() +
                    " [" +
                    logLevel2String( level ) +
                    "] " +
                    encfile(msg) +
                    "\n" )
                self.target.flush()
            except Exception as e:
                print("Error during writing to stdout: " +lastException2String() + "\n")

log = Logger( getLogTarget() )

log.debug( "pythonscript loading" )

#from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider
from com.sun.star.uno import RuntimeException
from com.sun.star.lang import XServiceInfo
from com.sun.star.io import IOException, XInputStream
from com.sun.star.ucb import CommandAbortedException, XCommandEnvironment, XProgressHandler, Command
from com.sun.star.task import XInteractionHandler
from com.sun.star.beans import XPropertySet, Property
from com.sun.star.container import XNameContainer
from com.sun.star.xml.sax import XDocumentHandler, InputSource
from com.sun.star.uno import Exception as UnoException
from com.sun.star.script import XInvocation
from com.sun.star.awt import XActionListener, FontDescriptor
from com.sun.star.awt.FontPitch import FIXED

from com.sun.star.script.provider import XScriptProvider, XScript, XScriptContext, ScriptFrameworkErrorException
from com.sun.star.script.browse import XBrowseNode
from com.sun.star.script.browse.BrowseNodeTypes import SCRIPT, CONTAINER, ROOT
from com.sun.star.util import XModifyListener

LANGUAGENAME = "Python"
GLOBAL_SCRIPTCONTEXT_NAME = "XSCRIPTCONTEXT"
CALLABLE_CONTAINER_NAME =  "g_exportedScripts"

# pythonloader looks for a static g_ImplementationHelper variable
g_ImplementationHelper = unohelper.ImplementationHelper()
g_implName = "org.openoffice.pyuno.LanguageScriptProviderFor"+LANGUAGENAME



BLOCK_SIZE = 65536
def readTextFromStream( inputStream ):
    # read the file
    code = uno.ByteSequence( b"" )
    while True:
        read,out = inputStream.readBytes( None , BLOCK_SIZE )
        code = code + out
        if read < BLOCK_SIZE:
            break
    if sys.version_info[0] > 2:
        return str( code.value, 'utf-8' )
    else:
        return code.value

def toIniName( str ):
    # TODO: what is the official way to get to know whether i am on the windows platform ?
    if( hasattr(sys , "dllhandle") ):
        return str + ".ini"
    return str + "rc"

class EmptyInputStream( unohelper.Base, XInputStream ):
    def __init__( self ):
        pass

    def closeInput(self):
        pass

    def readBytes( self, seq, n ):
        return 0, ""

    def readSomeBytes( self, seq, n ):
        return 0, ""

    def skipBytes( self, n ):
        pass

    def available( self ):
        return 0

class BytesInputStream( unohelper.Base, XInputStream ):
    def __init__( self, bytes ):
        self.bytes = bytes
        self.position = 0

    def closeInput(self):
        pass

    def readBytes( self, seq, n ):
        size = self.available()
        if n < size:
            size = n
        curr = self.position
        self.position += size
        return size, uno.ByteSequence( self.bytes[curr:curr+size] )

    def readSomeBytes( self, seq, n ):
        return self.readBytes( seq, n )

    def skipBytes( self, n ):
        size = self.available()
        if n < size:
            size = n
        self.position += size

    def available( self ):
        return len( self.bytes ) - self.position

""" definition: storageURI is the system dependent, absolute file url, where the script is stored on disk
                scriptURI is the system independent uri
"""
class MyUriHelper:

    def __init__( self, ctx, location ):
        self.s_UriMap = \
        { "share" : "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" +  toIniName( "bootstrap") + "::BaseInstallation}/share/Scripts/python" , \
          "share:uno_packages" : "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages", \
          "user" : "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" + toIniName( "bootstrap") + "::UserInstallation}/user/Scripts/python" , \
          "user:uno_packages" : "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages" }
        self.m_uriRefFac = ctx.ServiceManager.createInstanceWithContext("com.sun.star.uri.UriReferenceFactory",ctx)
        if location.startswith( "vnd.sun.star.tdoc" ):
            self.m_baseUri = location + "/Scripts/python"
            self.m_scriptUriLocation = "document"
        else:
            self.m_baseUri = expandUri( self.s_UriMap[location] )
            self.m_scriptUriLocation = location
        log.debug( "initialized urihelper with baseUri="+self.m_baseUri + ",m_scriptUriLocation="+self.m_scriptUriLocation )

    def getRootStorageURI( self ):
        return self.m_baseUri

    def getStorageURI( self, scriptURI ):
        return self.scriptURI2StorageUri(scriptURI)

    def getScriptURI( self, storageURI ):
        return self.storageURI2ScriptUri(storageURI)

    def storageURI2ScriptUri( self, storageURI ):
        if not storageURI.startswith( self.m_baseUri ):
            message = "pythonscript: storage uri '" + storageURI + "' not in base uri '" + self.m_baseUri + "'"
            log.debug( message )
            raise RuntimeException( message )

        ret = "vnd.sun.star.script:" + \
              storageURI[len(self.m_baseUri)+1:].replace("/","|") + \
              "?language=" + LANGUAGENAME + "&location=" + self.m_scriptUriLocation
        log.debug( "converting storageURI="+storageURI + " to scriptURI=" + ret )
        return ret

    def scriptURI2StorageUri( self, scriptURI ):
        try:
            myUri = self.m_uriRefFac.parse(scriptURI)
            ret = self.m_baseUri + "/" + myUri.getName().replace( "|", "/" )
            log.debug( "converting scriptURI="+scriptURI + " to storageURI=" + ret )
            return ret
        except UnoException as e:
            log.error( "error during converting scriptURI="+scriptURI + ": " + e.Message)
            raise RuntimeException( "pythonscript:scriptURI2StorageUri: " +e.getMessage(), None )
        except Exception as e:
            log.error( "error during converting scriptURI="+scriptURI + ": " + str(e))
            raise RuntimeException( "pythonscript:scriptURI2StorageUri: " + str(e), None )


class ModuleEntry:
    def __init__( self, lastRead, module ):
        self.lastRead = lastRead
        self.module = module

def hasChanged( oldDate, newDate ):
    return newDate.Year > oldDate.Year or \
           newDate.Month > oldDate.Month or \
           newDate.Day > oldDate.Day or \
           newDate.Hours > oldDate.Hours or \
           newDate.Minutes > oldDate.Minutes or \
           newDate.Seconds > oldDate.Seconds or \
           newDate.HundredthSeconds > oldDate.HundredthSeconds

def ensureSourceState( code ):
    if not code.endswith( "\n" ):
        code = code + "\n"
    code = code.replace( "\r", "" )
    return code


# Heuristics for Python 2 constructs that are *syntax* errors under Python 3.
# These fail at compile() time, so a runtime shim cannot fix them; the best we
# can do is recognise the most common ones and tell the user the script needs
# to be ported, instead of surfacing a bare SyntaxError traceback.
PYTHON2_SYNTAX_HINTS = (
    (re.compile( r"^\s*print\s+[^(=]" ),          "'print' statement (use the print() function)"),
    (re.compile( r"^\s*exec\s+[^(=]" ),           "'exec' statement (use the exec() function)"),
    (re.compile( r"\bexcept\b[^:]*,\s*\w+\s*:" ), "'except Exception, e:' syntax (use 'except Exception as e:')"),
    (re.compile( r"\braise\s+\w+\s*," ),          "'raise Exc, args' syntax (use 'raise Exc(args)')"),
    (re.compile( r"`[^`]+`" ),                     "backtick repr `x` (use repr(x))"),
    (re.compile( r"<>" ),                          "'<>' operator (use '!=')"),
    (re.compile( r"\b0[0-7]+\b" ),                 "old-style octal literal (use the 0o prefix)"),
    (re.compile( r"\b[uU][rR]['\"]" ),             "'ur' string prefix (removed in Python 3)"),
)

def detectPython2Syntax( src, syntaxError ):
    # Prefer the exact line the compiler flagged; fall back to scanning the source.
    candidates = []
    text = getattr( syntaxError, "text", None )
    if text:
        candidates.append( text )
    else:
        candidates = src.split( "\n" )
    for line in candidates:
        for pattern, description in PYTHON2_SYNTAX_HINTS:
            if pattern.search( line ):
                return description
    return None


def checkForPythonPathBesideScript( url ):
    if url.startswith( "file:" ):
        path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" );
        log.log( LogLevel.DEBUG,  "checking for existence of " + path )
        if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path:
            log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" )
            sys.path.append( path )

        path = unohelper.fileUrlToSystemPath( url+"/pythonpath" );
        log.log( LogLevel.DEBUG,  "checking for existence of " + path )
        if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path:
            log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" )
            sys.path.append( path )


class ScriptContext(unohelper.Base):
    def __init__( self, ctx, doc, inv ):
        self.ctx = ctx
        self.doc = doc
        self.inv = inv

   # XScriptContext
    def getDocument(self):
        if self.doc:
            return self.doc
        return self.getDesktop().getCurrentComponent()

    def getDesktop(self):
        return self.ctx.ServiceManager.createInstanceWithContext(
            "com.sun.star.frame.Desktop", self.ctx )

    def getComponentContext(self):
        return self.ctx

    def getInvocationContext(self):
        return self.inv

#----------------------------------
# Global Module Administration
# does not fit together with script
# engine lifetime management
#----------------------------------
#g_scriptContext = ScriptContext( uno.getComponentContext(), None )
#g_modules = {}
#def getModuleByUrl( url, sfa ):
#    entry =  g_modules.get(url)
#    load = True
#    lastRead = sfa.getDateTimeModified( url )
#    if entry:
#        if hasChanged( entry.lastRead, lastRead ):
#            log.debug("file " + url + " has changed, reloading")
#        else:
#            load = False
#
#    if load:
#        log.debug( "opening >" + url + "<" )
#
#        code = readTextFromStream( sfa.openFileRead( url ) )

        # execute the module
#        entry = ModuleEntry( lastRead, types.ModuleType("ooo_script_framework") )
#        entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext
#        entry.module.__file__ = url
#        exec code in entry.module.__dict__
#        g_modules[ url ] = entry
#        log.debug( "mapped " + url + " to " + str( entry.module ) )
#    return entry.module

class ProviderContext:
    def __init__( self, storageType, sfa, uriHelper, scriptContext ):
        self.storageType = storageType
        self.sfa = sfa
        self.uriHelper = uriHelper
        self.scriptContext = scriptContext
        self.modules = {}
        self.rootUrl = None
        self.mapPackageName2Path = None

    def getTransientPartFromUrl( self, url ):
        rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
        return rest[0:rest.find("/")]

    def getPackageNameFromUrl( self, url ):
        rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
        start = rest.find("/") +1
        return rest[start:rest.find("/",start)]


    def removePackageByUrl( self, url ):
        items = list(self.mapPackageName2Path.items())
        for i in items:
            if url in i[1].pathes:
                self.mapPackageName2Path.pop(i[0])
                break

    def addPackageByUrl( self, url ):
        packageName = self.getPackageNameFromUrl( url )
        transientPart = self.getTransientPartFromUrl( url )
        log.debug( "addPackageByUrl : " + packageName + ", " + transientPart + "("+url+")" + ", rootUrl="+self.rootUrl )
        if packageName in self.mapPackageName2Path:
            package = self.mapPackageName2Path[ packageName ]
            package.pathes = package.pathes + (url, )
        else:
            package = Package( (url,), transientPart)
            self.mapPackageName2Path[ packageName ] = package

    def isUrlInPackage( self, url ):
        values = list(self.mapPackageName2Path.values())
        for i in values:
#           print "checking " + url + " in " + str(i.pathes)
            if url in i.pathes:
                return True
#        print "false"
        return False

    def setPackageAttributes( self, mapPackageName2Path, rootUrl ):
        self.mapPackageName2Path = mapPackageName2Path
        self.rootUrl = rootUrl

    def getPersistentUrlFromStorageUrl( self, url ):
        # package name is the second directory
        ret = url
        if self.rootUrl:
            pos = len( self.rootUrl) +1
            ret = url[0:pos]+url[url.find("/",pos)+1:len(url)]
        log.debug( "getPersistentUrlFromStorageUrl " + url +  " -> "+ ret)
        return ret

    def getStorageUrlFromPersistentUrl( self, url):
        ret = url
        if self.rootUrl:
            pos = len(self.rootUrl)+1
            packageName = url[pos:url.find("/",pos+1)]
            package = self.mapPackageName2Path[ packageName ]
            ret = url[0:pos]+ package.transientPathElement + "/" + url[pos:len(url)]
        log.debug( "getStorageUrlFromPersistentUrl " + url + " -> "+ ret)
        return ret

    def getFuncsByUrl( self, url ):
        src = readTextFromStream( self.sfa.openFileRead( url ) )
        checkForPythonPathBesideScript( url[0:url.rfind('/')] )
        src = ensureSourceState( src )

        allFuncs = []
        g_exportedScripts = []

        a = ast.parse(src, url)

        if isinstance(a, ast.Module):
            for node in a.body:
                if isinstance(node, ast.FunctionDef):
                    allFuncs.append(node.name)
                elif isinstance(node, ast.Assign):
                    is_exported = False
                    for subnode in node.targets:
                        if isinstance(subnode, ast.Name) and \
                            subnode.id == "g_exportedScripts":
                            is_exported = True
                            break
                    if is_exported:
                        value_node = node.value
                        if isinstance(value_node, ast.List) or \
                            isinstance(value_node, ast.Tuple):
                            for elt in value_node.elts:
                                if isinstance(elt, ast.Str):
                                    g_exportedScripts.append(elt.s)
                                elif isinstance(elt, ast.Name):
                                    g_exportedScripts.append(elt.id)
                        elif isinstance(value_node, ast.Str):
                            g_exportedScripts.append(value_node.s)
                        elif isinstance(value_node, ast.Name):
                            g_exportedScripts.append(value_node.id)
                        return g_exportedScripts
        return allFuncs

    def getModuleByUrl( self, url ):
        entry =  self.modules.get(url)
        load = True
        lastRead = self.sfa.getDateTimeModified( url )
        if entry:
            if hasChanged( entry.lastRead, lastRead ):
                log.debug( "file " + url + " has changed, reloading" )
            else:
                load = False

        if load:
            log.debug( "opening >" + url + "<" )

            src = readTextFromStream( self.sfa.openFileRead( url ) )
            checkForPythonPathBesideScript( url[0:url.rfind('/')] )
            src = ensureSourceState( src )

            # execute the module
            entry = ModuleEntry( lastRead, types.ModuleType("ooo_script_framework") )
            entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.scriptContext

            code = None
            scriptName = uno.fileUrlToSystemPath( url ) if url.startswith( "file:" ) else url
            try:
                code = compile( src, encfile(scriptName) if url.startswith( "file:" ) else url, "exec" )
            except SyntaxError as e:
                hint = detectPython2Syntax( src, e )
                if hint:
                    raise SyntaxError(
                        "The script '" + scriptName + "' appears to use Python 2 syntax that is "
                        "not valid in Python 3: " + hint + ". Please port the script to Python 3. "
                        "(original error: " + str(e) + ")" )
                raise
            exec(code, entry.module.__dict__)
            entry.module.__file__ = url
            self.modules[ url ] = entry
            log.debug( "mapped " + url + " to " + str( entry.module ) )
        return  entry.module

    # Forgets a stale module so a fresh copy can be loaded in the future.
    # This is necessary because getModuleByUrl()'s self.sfa.getDateTimeModified()
    # doesn't always work, eg. for embedded scripts it always returns timestamps
    # with all zeroes, and even if it worked, the smallest granularity for ZIP file
    # timestamps is 2 seconds, which isn't good enough.
    def removeModuleByUrl( self, url ):
        self.modules.pop( url, None )

def createEditorDialog( ctx ):
    smgr = ctx.ServiceManager

    dialogModel = smgr.createInstanceWithContext(
        "com.sun.star.awt.UnoControlDialogModel", ctx)
    dialogModel.PositionX = 105
    dialogModel.PositionY = 117
    dialogModel.Width = 240
    dialogModel.Height = 320
    dialogModel.Closeable = True
    dialogModel.Moveable = True
    dialogModel.Title = "Python Macro Editor"

    runButtonModel = dialogModel.createInstance(
        "com.sun.star.awt.UnoControlButtonModel" )
    runButtonModel.PositionX = 57
    runButtonModel.PositionY = 300
    runButtonModel.Width = 40
    runButtonModel.Height = 14
    runButtonModel.TabIndex = 0
    runButtonModel.Label = "Run"

    saveButtonModel = dialogModel.createInstance(
        "com.sun.star.awt.UnoControlButtonModel" )
    saveButtonModel.PositionX = 100
    saveButtonModel.PositionY = 300
    saveButtonModel.Width = 40
    saveButtonModel.Height = 14
    saveButtonModel.TabIndex = 1
    saveButtonModel.Label = "Save"

    closeButtonModel = dialogModel.createInstance(
        "com.sun.star.awt.UnoControlButtonModel" )
    closeButtonModel.PositionX = 143
    closeButtonModel.PositionY = 300
    closeButtonModel.Width = 40
    closeButtonModel.Height = 14
    closeButtonModel.TabIndex = 2
    closeButtonModel.PushButtonType = 2  # CANCEL
    closeButtonModel.Label = "Close"

    fontDescriptor = FontDescriptor()
    fontDescriptor.Name = "SomeFixedWidthFont"
    fontDescriptor.Pitch = FIXED

    textFieldModel = dialogModel.createInstance(
        "com.sun.star.awt.UnoControlEditModel" )
    textFieldModel.PositionX = 6
    textFieldModel.PositionY = 6
    textFieldModel.Width = 228
    textFieldModel.Height = 288
    textFieldModel.TabIndex = 3
    textFieldModel.HScroll = True
    textFieldModel.VScroll = True
    textFieldModel.MultiLine = True
    textFieldModel.FontDescriptor = fontDescriptor

    dialogModel.insertByName( "RunButton", runButtonModel )
    dialogModel.insertByName( "SaveButton", saveButtonModel )
    dialogModel.insertByName( "CloseButton", closeButtonModel )
    dialogModel.insertByName( "EditorTextField", textFieldModel )

    # create the dialog control and set the model
    controlContainer = smgr.createInstanceWithContext(
        "com.sun.star.awt.UnoControlDialog", ctx);
    controlContainer.setModel(dialogModel);

    # create a peer
    toolkit = smgr.createInstanceWithContext(
        "com.sun.star.awt.ExtToolkit", ctx);

    controlContainer.setVisible(False);
    controlContainer.createPeer(toolkit, None);

    return controlContainer


#--------------------------------------------------
def isScript( candidate ):
    ret = False
    if isinstance( candidate, type(isScript) ):
        ret = True
    return ret

#-------------------------------------------------------
class ScriptBrowseNode( unohelper.Base, XBrowseNode, XPropertySet, XInvocation, XActionListener ):
    def __init__( self, provCtx, parent, fileName, funcName ):
        self.parent = parent
        self.fileName = fileName
        self.funcName = funcName
        self.provCtx = provCtx

    def uri( self ):
        return self.parent.uri()

    def getName( self ):
        return self.funcName

    def getChildNodes(self):
        return ()

    def hasChildNodes(self):
        return False

    def getType( self):
        return SCRIPT

    def getPropertyValue( self, name ):
        ret = None
        try:
            if name == "URI":
                ret = self.provCtx.uriHelper.getScriptURI(
                    self.provCtx.getPersistentUrlFromStorageUrl( self.uri() + "$" + self.funcName ) )
            elif name == "Editable":
                ret = not self.provCtx.sfa.isReadOnly( self.uri() )

            log.debug( "ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) )
        except Exception as e:
            log.error( "ScriptBrowseNode.getPropertyValue error " + lastException2String())
            raise

        return ret
    def setPropertyValue( self, name, value ):
        log.debug( "ScriptBrowseNode.setPropertyValue called " + name + "=" +str(value ) )
    def getPropertySetInfo( self ):
        log.debug( "ScriptBrowseNode.getPropertySetInfo called "  )
        return None

    def getIntrospection( self ):
        return None

    def invoke( self, name, params, outparamindex, outparams ):
        if name == "Editable":
            ctx = self.provCtx.scriptContext.getComponentContext()

            self.editor = createEditorDialog( ctx )

            code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri()))
            code = ensureSourceState( code )
            self.editor.getControl("EditorTextField").setText(code)

            self.editor.getControl("RunButton").setActionCommand("Run")
            self.editor.getControl("RunButton").addActionListener(self)
            self.editor.getControl("SaveButton").setActionCommand("Save")
            self.editor.getControl("SaveButton").addActionListener(self)

            self.editor.execute()

        return None, (), ()

    def actionPerformed( self, event ):
        try:
            if event.ActionCommand == "Run":
                code = self.editor.getControl("EditorTextField").getText()
                code = ensureSourceState( code )
                mod = types.ModuleType("ooo_script_framework")
                mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext
                exec(code, mod.__dict__)
                values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
                if not values:
                    values = list(mod.__dict__.values())

                for i in values:
                    if isScript( i ):
                        i()
                        break

            elif event.ActionCommand == "Save":
                toWrite = uno.ByteSequence(
                    self.editor.getControl("EditorTextField").getText().encode("utf-8"))
                log.debug( "Saving Python macro to URI " + self.uri() )
                self.provCtx.sfa.writeFile( self.uri(), BytesInputStream( toWrite.value ) )
                self.provCtx.removeModuleByUrl( self.uri() )
        except Exception as e:
            # TODO: add an error box here !
            log.error( lastException2String() )


    def setValue( self, name, value ):
        return None

    def getValue( self, name ):
        return None

    def hasMethod( self, name ):
        return False

    def hasProperty( self, name ):
        return False


#-------------------------------------------------------
class FileBrowseNode( unohelper.Base, XBrowseNode, XPropertySet, XInvocation, XActionListener ):
    def __init__( self, provCtx, parent, name ):
        self.provCtx = provCtx
        self.parent = parent
        self.name = name
        self.funcnames = None

    def uri( self ):
        return self.parent.rootUrl + "/" + self.name + ".py"

    def getName( self ):
        return self.name

    def getChildNodes(self):
        ret = ()
        try:
            self.funcnames = self.provCtx.getFuncsByUrl( self.uri() )

            scriptNodeList = []
            for i in self.funcnames:
                scriptNodeList.append(
                    ScriptBrowseNode(
                    self.provCtx, self, self.name, i ))
            ret = tuple( scriptNodeList )
        except Exception as e:
            text = lastException2String()
            log.error( "FileBrowseNode.getChildNodes error while evaluating " + self.uri() + ":" + text )
            raise
        return ret

    def hasChildNodes(self):
        try:
            return len(self.getChildNodes()) > 0
        except Exception as e:
            return False

    def getType( self):
        return CONTAINER

    # XPropertySet

    def getPropertyValue( self, name ):
        ret = None
        try:
            if name == "Editable":
                ret = not self.provCtx.sfa.isReadOnly( self.uri() )
            elif name == "Deletable":
                ret = not self.provCtx.sfa.isReadOnly( self.uri() )
            elif name == "Renamable":
                ret = not self.provCtx.sfa.isReadOnly( self.uri() )

            log.debug( "FileBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) )
        except Exception as e:
            log.error( "FileBrowseNode.getPropertyValue error " + lastException2String())
            raise

        return ret

    def setPropertyValue( self, name, value ):
        log.debug( "FileBrowseNode.setPropertyValue called " + name + "=" +str(value ) )

    def getPropertySetInfo( self ):
        log.debug( "FileBrowseNode.getPropertySetInfo called "  )
        return None

    # XInvocation

    def getIntrospection( self ):
        log.debug( "FileBrowseNode.getIntrospection() called" )
        return None

    def invoke( self, name, params, outparamindex, outparams ):
        log.debug("FileBrowseNode.invoke called for " + name + "," + str(params) + "," + str(outparamindex) + "," + str(outparams))
        try:
            if name == "Editable":
                ctx = self.provCtx.scriptContext.getComponentContext()

                self.editor = createEditorDialog( ctx )

                code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri()))
                code = ensureSourceState( code )
                self.editor.getControl("EditorTextField").setText(code)

                self.editor.getControl("RunButton").setActionCommand("Run")
                self.editor.getControl("RunButton").addActionListener(self)
                self.editor.getControl("SaveButton").setActionCommand("Save")
                self.editor.getControl("SaveButton").addActionListener(self)

                self.editor.execute()
            elif name == "Deletable":
                self.provCtx.sfa.kill( self.uri() )
                return True, (), ()
            elif name == "Renamable":
                if params is None or not params:
                    raise IllegalArgumentException( "invoke with Creatable needs the name in params" )
                newUri = self.parent.rootUrl + "/" + params[0] + ".py"
                self.provCtx.sfa.move( self.uri(), newUri )
                self.name = params[0]
                return self, (), ()
        except Exception as e:
            log.error( "FileBrowseNode.invoke error " + lastException2String() )
            raise
        return None, (), ()

    def setValue( self, name, value ):
        return None

    def getValue( self, name ):
        log.debug( "FileBrowseNode.getValue() called" )
        return None

    def hasMethod( self, name ):
        return False

    def hasProperty( self, name ):
        return False

    # XActionListener

    def actionPerformed( self, event ):
        try:
            if event.ActionCommand == "Run":
                code = self.editor.getControl("EditorTextField").getText()
                code = ensureSourceState( code )
                mod = types.ModuleType("ooo_script_framework")
                mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext
                exec(code, mod.__dict__)
                values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
                if not values:
                    values = list(mod.__dict__.values())

                for i in values:
                    if isScript( i ):
                        i()
                        break

            elif event.ActionCommand == "Save":
                toWrite = uno.ByteSequence(
                    self.editor.getControl("EditorTextField").getText().encode("utf-8"))
                log.debug( "Saving Python macro to URI " + self.uri() )
                self.provCtx.sfa.writeFile( self.uri(), BytesInputStream( toWrite.value ) )
                self.provCtx.removeModuleByUrl( self.uri() )
        except Exception as e:
            # TODO: add an error box here !
            log.error( lastException2String() )


class DirBrowseNode( unohelper.Base, XBrowseNode, XPropertySet, XInvocation ):
    def __init__( self, provCtx, name, rootUrl, depth ):
        self.provCtx = provCtx
        self.name = name
        self.rootUrl = rootUrl
        self.depth = depth
        log.debug( "DirBrowseNode constructor for " + name + "," + rootUrl )

    def getName( self ):
        return self.name

    def getChildNodes( self ):
        try:
            log.debug( "DirBrowseNode.getChildNodes called for " + self.rootUrl )
            contents = self.provCtx.sfa.getFolderContents( self.rootUrl, True )
            browseNodeList = []
            for i in contents:
                if i.endswith( ".py" ):
                    log.debug( "adding filenode " + i )
                    browseNodeList.append(
                        FileBrowseNode( self.provCtx, self, i[i.rfind("/")+1:len(i)-3] ) )
                elif self.provCtx.sfa.isFolder( i ) and not i.endswith("/pythonpath"):
                    log.debug( "adding DirBrowseNode " + i )
                    browseNodeList.append(
                        DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)], i, self.depth + 1 ) )
            return tuple( browseNodeList )
        except Exception as e:
            text = lastException2String()
            log.error( "DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl)
            log.error( text)
            return ()

    def hasChildNodes( self ):
        return True

    def getType( self ):
        return CONTAINER

    # XScriptProvider

    def getScript( self, uri ):
        log.debug( "DirBrowseNode getScript " + uri + " invoked" )
        raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 )

    # XPropertySet

    def getPropertyValue( self, name ):
        ret = None
        try:
            if name == "Creatable":
                ret = True
            elif name == "Deletable":
                ret = self.depth > 0 and not self.provCtx.sfa.isReadOnly( self.rootUrl )
            elif name == "Renamable":
                ret = self.depth > 0 and not self.provCtx.sfa.isReadOnly( self.rootUrl )

            log.debug( "DirBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) )
        except Exception as e:
            log.error( "DirBrowseNode.getPropertyValue error " + lastException2String())
            raise

        return ret

    def setPropertyValue( self, name, value ):
        log.debug( "DirBrowseNode.setPropertyValue called " + name + "=" +str(value ) )

    def getPropertySetInfo( self ):
        log.debug( "DirBrowseNode.getPropertySetInfo called "  )
        return None

    # XInvocation

    def getIntrospection( self ):
        log.debug( "DirBrowseNode.getIntrospection() called" )
        return None

    def invoke( self, name, params, outparamindex, outparams ):
        log.debug("DirBrowseNode.invoke called for " + name + "," + str(params) + "," + str(outparamindex) + "," + str(outparams))
        try:
            if name == "Creatable":
                if params is None or not params:
                    raise IllegalArgumentException( "invoke with Creatable needs the name in params" )
                if self.depth == 0:
                    subFolderUrl = self.rootUrl + "/" + params[0]
                    self.provCtx.sfa.createFolder( subFolderUrl )
                    childNode = DirBrowseNode( self.provCtx, subFolderUrl[subFolderUrl.rfind("/")+1:len(subFolderUrl)], subFolderUrl, self.depth + 1 )
                    return childNode, (), ()
                else:
                    scriptUrl = self.rootUrl + "/" + params[0] + ".py"
                    # Creates an empty file
                    self.provCtx.sfa.writeFile( scriptUrl, EmptyInputStream() )
                    childNode = FileBrowseNode( self.provCtx, self, params[0] )
                    return childNode, (), ()
            elif name == "Deletable":
                self.provCtx.sfa.kill( self.rootUrl )
                return True, (), ()
            elif name == "Renamable":
                if params is None or not params:
                    raise IllegalArgumentException( "invoke with Renamable needs the name in params" )
                newUrl = self.rootUrl[0:self.rootUrl.rfind("/")+1] + params[0]
                self.provCtx.sfa.move( self.rootUrl, newUrl )
                self.rootUrl = newUrl
                self.name = params[0]
                return self, (), ()
        except Exception as e:
            log.error( "DirBrowseNode.invoke error: " + lastException2String())
            raise
        return None, (), ()

    def setValue( self, name, value ):
        return None

    def getValue( self, name ):
        log.debug( "DirBrowseNode.getValue() called" )
        return None

    def hasMethod( self, name ):
        return False

    def hasProperty( self, name ):
        return False


class ManifestHandler( XDocumentHandler, unohelper.Base ):
    def __init__( self, rootUrl ):
        self.rootUrl = rootUrl

    def startDocument( self ):
        self.urlList = []

    def endDocument( self ):
        pass

    def startElement( self , name, attlist):
        if name == "manifest:file-entry":
            if attlist.getValueByName( "manifest:media-type" ) == "application/vnd.sun.star.framework-script":
                self.urlList.append(
                    self.rootUrl + "/" + attlist.getValueByName( "manifest:full-path" ) )

    def endElement( self, name ):
        pass

    def characters ( self, chars ):
        pass

    def ignoreableWhitespace( self, chars ):
        pass

    def setDocumentLocator( self, locator ):
        pass

def isPyFileInPath( sfa, path ):
    ret = False
    contents = sfa.getFolderContents( path, True )
    for i in contents:
        if sfa.isFolder(i):
            ret = isPyFileInPath(sfa,i)
        else:
            if i.endswith(".py"):
                ret = True
        if ret:
            break
    return ret

# extracts META-INF directory from
def getPathesFromPackage( rootUrl, sfa ):
    ret = ()
    try:
        fileUrl = rootUrl + "/META-INF/manifest.xml"
        inputStream = sfa.openFileRead( fileUrl )
        parser = uno.getComponentContext().ServiceManager.createInstance( "com.sun.star.xml.sax.Parser" )
        handler = ManifestHandler( rootUrl )
        parser.setDocumentHandler( handler )
        parser.parseStream( InputSource( inputStream , "", fileUrl, fileUrl ) )
        for i in tuple(handler.urlList):
            if not isPyFileInPath( sfa, i ):
                handler.urlList.remove(i)
        ret = tuple( handler.urlList )
    except UnoException as e:
        text = lastException2String()
        log.debug( "getPathesFromPackage " + fileUrl + " Exception: " +text )
        pass
    return ret


class Package:
    def __init__( self, pathes, transientPathElement ):
        self.pathes = pathes
        self.transientPathElement = transientPathElement

class DummyInteractionHandler( unohelper.Base, XInteractionHandler ):
    def __init__( self ):
        pass
    def handle( self, event):
        log.debug( "pythonscript: DummyInteractionHandler.handle " + str( event ) )

class DummyProgressHandler( unohelper.Base, XProgressHandler ):
    def __init__( self ):
        pass

    def push( self,status ):
        log.debug( "pythonscript: DummyProgressHandler.push " + str( status ) )
    def update( self,status ):
        log.debug( "pythonscript: DummyProgressHandler.update " + str( status ) )
    def pop( self ):
        log.debug( "pythonscript: DummyProgressHandler.push " + str( event ) )

class CommandEnvironment(unohelper.Base, XCommandEnvironment):
    def __init__( self ):
        self.progressHandler = DummyProgressHandler()
        self.interactionHandler = DummyInteractionHandler()
    def getInteractionHandler( self ):
        return self.interactionHandler
    def getProgressHandler( self ):
        return self.progressHandler

#maybe useful for debugging purposes
#class ModifyListener( unohelper.Base, XModifyListener ):
#    def __init__( self ):
#        pass
#    def modified( self, event ):
#        log.debug( "pythonscript: ModifyListener.modified " + str( event ) )
#    def disposing( self, event ):
#        log.debug( "pythonscript: ModifyListener.disposing " + str( event ) )

def getModelFromDocUrl(ctx, url):
    """Get document model from document url."""
    doc = None
    args = ("Local", "Office")
    ucb = ctx.getServiceManager().createInstanceWithArgumentsAndContext(
        "com.sun.star.ucb.UniversalContentBroker", args, ctx)
    identifier = ucb.createContentIdentifier(url)
    content = ucb.queryContent(identifier)
    p = Property()
    p.Name = "DocumentModel"
    p.Handle = -1

    c = Command()
    c.Handle = -1
    c.Name = "getPropertyValues"
    c.Argument = uno.Any("[]com.sun.star.beans.Property", (p,))

    env = CommandEnvironment()
    try:
        ret = content.execute(c, 0, env)
        doc = ret.getObject(1, None)
    except Exception as e:
        log.isErrorLevel() and log.error("getModelFromDocUrl: %s" % url)
    return doc

def mapStorageType2PackageContext( storageType ):
    ret = storageType
    if( storageType == "share:uno_packages" ):
        ret = "shared"
    if( storageType == "user:uno_packages" ):
        ret = "user"
    return ret

def getPackageName2PathMap( sfa, storageType ):
    ret = {}
    packageManagerFactory = uno.getComponentContext().getValueByName(
        "/singletons/com.sun.star.deployment.thePackageManagerFactory" )
    packageManager = packageManagerFactory.getPackageManager(
        mapStorageType2PackageContext(storageType))
#    packageManager.addModifyListener( ModifyListener() )
    log.debug( "pythonscript: getPackageName2PathMap start getDeployedPackages" )
    packages = packageManager.getDeployedPackages(
        packageManager.createAbortChannel(), CommandEnvironment( ) )
    log.debug( "pythonscript: getPackageName2PathMap end getDeployedPackages (" + str(len(packages))+")" )

    for i in packages:
        log.debug( "inspecting package " + i.Name + "("+i.Identifier.Value+")" )
        transientPathElement = penultimateElement( i.URL )
        j = expandUri( i.URL )
        pathes = getPathesFromPackage( j, sfa )
        if len( pathes ) > 0:
            # map package name to url, we need this later
            log.isErrorLevel() and log.error( "adding Package " + transientPathElement + " " + str( pathes ) )
            ret[ lastElement( j ) ] = Package( pathes, transientPathElement )
    return ret

def penultimateElement( aStr ):
    lastSlash = aStr.rindex("/")
    penultimateSlash = aStr.rindex("/",0,lastSlash-1)
    return  aStr[ penultimateSlash+1:lastSlash ]

def lastElement( aStr):
    return aStr[ aStr.rfind( "/" )+1:len(aStr)]

class PackageBrowseNode( unohelper.Base, XBrowseNode, XPropertySet, XInvocation ):
    def __init__( self, provCtx, name, rootUrl ):
        self.provCtx = provCtx
        self.name = name
        self.rootUrl = rootUrl

    def getName( self ):
        return self.name

    def getChildNodes( self ):
        items = list(self.provCtx.mapPackageName2Path.items())
        browseNodeList = []
        for i in items:
            if len( i[1].pathes ) == 1:
                browseNodeList.append(
                    DirBrowseNode( self.provCtx, i[0], i[1].pathes[0], 0 ))
            else:
                for j in i[1].pathes:
                    browseNodeList.append(
                        DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j), j, 0 ) )
        return tuple( browseNodeList )

    def hasChildNodes( self ):
        return len( self.mapPackageName2Path ) > 0

    def getType( self ):
        return CONTAINER

    def getScript( self, uri ):
        log.debug( "DirBrowseNode getScript " + uri + " invoked" )
        raise IllegalArgumentException( "PackageBrowseNode couldn't instantiate script " + uri , self , 0 )

    # XPropertySet

    def getPropertyValue( self, name ):
        ret = None
        log.debug( "PackageBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) )
        return ret

    def setPropertyValue( self, name, value ):
        log.debug( "PackageBrowseNode.setPropertyValue " + name + "=" +str( value ) )

    def getPropertySetInfo( self ):
        log.debug( "PackageBrowseNode.getPropertySetInfo called" )
        return None

    # XInvocation

    def getIntrospection( self ):
        log.debug( "PackageBrowseNode.getIntrospection() called" )
        return None

    def invoke( self, name, params, outparamindex, outparams ):
        log.debug( "PackageBrowseNode.invoke called for " + name + "," + str( params ) + "," + str( outparamindex ) + "," + str( outparams ) )
        return None, (), ()

    def setValue( self, name, value ):
        log.debug( "PackageBrowseNode.setValue" )
        return None

    def getValue( self, name ):
        log.debug( "PackageBrowseNode.getValue" )
        return None

    def hasMethod( self, name ):
        log.debug( "PackageBrowseNode.hasMethod" )
        return False

    def hasProperty( self, name ):
        log.debug( "PackageBrowseNode.hasProperty" )
        return False



class PythonScript( unohelper.Base, XScript ):
    def __init__( self, func, mod ):
        self.func = func
        self.mod = mod
    def invoke(self, args, out, outindex ):
        log.debug( "PythonScript.invoke " + str( args ) )
        try:
            ret = self.func( *args )
        except UnoException as e:
            # UNO Exception continue to fly ...
            text = lastException2String()
            complete = "Error during invoking function " + \
                str(self.func.__name__) + " in module " + \
                self.mod.__file__ + " (" + text + ")"
            log.debug( complete )
            # some people may beat me up for modifying the exception text,
            # but otherwise office just shows
            # the type name and message text with no more information,
            # this is really bad for most users.
            e.Message = e.Message + " (" + complete + ")"
            raise
        except Exception as e:
            # General python exception are converted to uno RuntimeException
            text = lastException2String()
            complete = "Error during invoking function " + \
                str(self.func.__name__) + " in module " + \
                self.mod.__file__ + " (" + text + ")"
            log.debug( complete )
            raise RuntimeException( complete , self )
        log.debug( "PythonScript.invoke ret = " + str( ret ) )
        return ret, (), ()

def expandUri(  uri ):
    if uri.startswith( "vnd.sun.star.expand:" ):
        uri = uri.replace( "vnd.sun.star.expand:", "",1)
        uri = uno.getComponentContext().getByName(
                    "/singletons/com.sun.star.util.theMacroExpander" ).expandMacros( uri )
    if uri.startswith( "file:" ):
        uri = uno.absolutize("",uri)   # necessary to get rid of .. in uri
    return uri

#--------------------------------------------------------------
class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer, XPropertySet, XInvocation):
    def __init__( self, ctx, *args ):
        if log.isDebugLevel():
            mystr = ""
            for i in args:
                if len(mystr) > 0:
                    mystr = mystr +","
                mystr = mystr + str(i)
            log.debug( "Entering PythonScriptProvider.ctor with args " + mystr )

        doc = None
        inv = None
        storageType = ""

        if isinstance(args[0],unicode ):
            storageType = args[0]
            if storageType.startswith( "vnd.sun.star.tdoc" ):
                doc = getModelFromDocUrl(ctx, storageType)
        else:
            inv = args[0]
            try:
                doc = inv.ScriptContainer
                content = ctx.getServiceManager().createInstanceWithContext(
                    "com.sun.star.frame.TransientDocumentsDocumentContentFactory",
                    ctx).createDocumentContent(doc)
                storageType = content.getIdentifier().getContentIdentifier()
            except Exception as e:
                text = lastException2String()
                log.error( text )

        isPackage = storageType.endswith( ":uno_packages" )

        try:
#            urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext(
#                "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx)
            urlHelper = MyUriHelper( ctx, storageType )
            log.debug( "got urlHelper " + str( urlHelper ) )

            rootUrl = expandUri( urlHelper.getRootStorageURI() )
            log.debug( storageType + " transformed to " + rootUrl )

            ucbService = "com.sun.star.ucb.SimpleFileAccess"
            sfa = ctx.ServiceManager.createInstanceWithContext( ucbService, ctx )
            if not sfa:
                log.debug("PythonScriptProvider couldn't instantiate " +ucbService)
                raise RuntimeException(
                    "PythonScriptProvider couldn't instantiate " +ucbService, self)
            self.provCtx = ProviderContext(
                storageType, sfa, urlHelper, ScriptContext( uno.getComponentContext(), doc, inv ) )
            if isPackage:
                mapPackageName2Path = getPackageName2PathMap( sfa, storageType )
                self.provCtx.setPackageAttributes( mapPackageName2Path , rootUrl )
                self.dirBrowseNode = PackageBrowseNode( self.provCtx, LANGUAGENAME, rootUrl )
            else:
                self.dirBrowseNode = DirBrowseNode( self.provCtx, LANGUAGENAME, rootUrl, 0 )

        except Exception as e:
            text = lastException2String()
            log.debug( "PythonScriptProvider could not be instantiated because of : " + text )
            raise e

    def getName( self ):
        return self.dirBrowseNode.getName()

    def getChildNodes( self ):
        return self.dirBrowseNode.getChildNodes()

    def hasChildNodes( self ):
        return self.dirBrowseNode.hasChildNodes()

    def getType( self ):
        return self.dirBrowseNode.getType()

    def getScript( self, scriptUri ):
        try:
            log.debug( "DirBrowseNode getScript " + scriptUri + " invoked")

            storageUri = self.provCtx.getStorageUrlFromPersistentUrl(
                self.provCtx.uriHelper.getStorageURI(scriptUri) );
            log.debug( "getScript: storageUri = " + storageUri)
            fileUri = storageUri[0:storageUri.find( "$" )]
            funcName = storageUri[storageUri.find( "$" )+1:len(storageUri)]

            mod = self.provCtx.getModuleByUrl( fileUri )
            log.debug( " got mod " + str(mod) )

            func = mod.__dict__[ funcName ]

            log.debug( "got func " + str( func ) )
            return PythonScript( func, mod )
        except Exception as e:
            text = lastException2String()
            log.error( text )
            raise ScriptFrameworkErrorException( text, self, scriptUri, LANGUAGENAME, 0 )

    # XPropertySet

    def getPropertyValue( self, name ):
        return self.dirBrowseNode.getPropertyValue( name )

    def setPropertyValue( self, name, value ):
        return self.dirBrowseNode.setPropertyValue( name, value )

    def getPropertySetInfo( self ):
        return self.dirBrowseNode.getPropertySetInfo()

    # XInvocation

    def getIntrospection( self ):
        return self.dirBrowseNode.getIntrospection()

    def invoke( self, name, params, outparamindex, outparams ):
        return self.dirBrowseNode.invoke( name, params, outparamindex, outparams)

    def setValue( self, name, value ):
        return self.dirBrowseNode.setValue( name, value )

    def getValue( self, name ):
        return self.dirBrowseNode.getValue( name )

    def hasMethod( self, name ):
        return self.dirBrowseNode.hasMethod( name )

    def hasProperty( self, name ):
        return self.dirBrowseNode.hasProperty( name )

    # XServiceInfo
    def getSupportedServices( self ):
        return g_ImplementationHelper.getSupportedServices(g_implName)

    def supportsService( self, ServiceName ):
        return g_ImplementationHelper.supportsService( g_implName, ServiceName )

    def getImplementationName(self):
        return g_implName

    def getByName( self, name ):
        log.debug( "getByName called" + str( name ))
        return None


    def getElementNames( self ):
        log.debug( "getElementNames called")
        return ()

    def hasByName( self, name ):
        try:
            log.debug( "hasByName called " + str( name ))
            uri = expandUri(name)
            ret = self.provCtx.isUrlInPackage( uri )
            log.debug( "hasByName " + uri + " " +str( ret ) )
            return ret
        except Exception as e:
            text = lastException2String()
            log.debug( "Error in hasByName:" +  text )
            return False

    def removeByName( self, name ):
        log.debug( "removeByName called" + str( name ))
        uri = expandUri( name )
        if self.provCtx.isUrlInPackage( uri ):
            self.provCtx.removePackageByUrl( uri )
        else:
            log.debug( "removeByName unknown uri " + str( name ) + ", ignoring" )
            raise NoSuchElementException( uri + "is not in package" , self )
        log.debug( "removeByName called" + str( uri ) + " successful" )

    def insertByName( self, name, value ):
        log.debug( "insertByName called " + str( name ) + " " + str( value ))
        uri = expandUri( name )
        if isPyFileInPath( self.provCtx.sfa, uri ):
            self.provCtx.addPackageByUrl( uri )
        else:
            # package is no python package ...
            log.debug( "insertByName: no python files in " + str( uri ) + ", ignoring" )
            raise IllegalArgumentException( uri + " does not contain .py files", self, 1 )
        log.debug( "insertByName called " + str( uri ) + " successful" )

    def replaceByName( self, name, value ):
        log.debug( "replaceByName called " + str( name ) + " " + str( value ))
        removeByName( name )
        insertByName( name )
        log.debug( "replaceByName called" + str( uri ) + " successful" )

    def getElementType( self ):
        log.debug( "getElementType called" )
        return uno.getTypeByName( "void" )

    def hasElements( self ):
        log.debug( "hasElements got called")
        return False

g_ImplementationHelper.addImplementation( \
        PythonScriptProvider,g_implName, \
    ("com.sun.star.script.provider.LanguageScriptProvider",
     "com.sun.star.script.provider.ScriptProviderFor"+ LANGUAGENAME,),)


log.debug( "pythonscript finished initializing" )
