packagetree.py :  » Development » HappyDoc » HappyDoc3-r3_1 » happydoclib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Development » HappyDoc 
HappyDoc » HappyDoc3 r3_1 » happydoclib » packagetree.py
#!/usr/bin/env python
#
# $Id: packagetree.py,v 1.11 2006/12/05 13:10:45 doughellmann Exp $
#
# Copyright 2002 Doug Hellmann.
#
#
#                         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 both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of Doug
# Hellmann not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior
# permission.
#
# DOUG HELLMANN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
# NO EVENT SHALL DOUG HELLMANN 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.
#

"""Tree representing the input data.

"""

__rcs_info__ = {
    #
    #  Creation Information
    #
    'module_name'  : '$RCSfile: packagetree.py,v $',
    'rcs_id'       : '$Id: packagetree.py,v 1.11 2006/12/05 13:10:45 doughellmann Exp $',
    'creator'      : 'Doug Hellmann',
    'project'      : 'HappyDoc',
    'created'      : 'Sun, 29-Dec-2002 12:37:53 EST',

    #
    #  Current Information
    #
    'author'       : '$Author: doughellmann $',
    'version'      : '$Revision: 1.11 $',
    'date'         : '$Date: 2006/12/05 13:10:45 $',
}
try:
    __version__ = __rcs_info__['version'].split(' ')[1]
except:
    __version__ = '0.0'

#
# Import system modules
#
import os
import pprint
import re
import UserDict


#
# Import Local modules
#
import happydoclib
from happydoclib.status import statusMessage
from happydoclib.trace import trace
from happydoclib.utils import getMimeType


#
# Module
#

TRACE_LEVEL=2


class PackageTree(UserDict.UserDict):
    """Tree of package information.

    Access each child node using the standard mapping de-reference
    syntax ([], .get(), etc.).
    """

    def __init__(self, parent, name):
        trace.into('PackageTree', '__init__',
                   name=name,
                   outputLevel=TRACE_LEVEL,
                   )
        UserDict.UserDict.__init__(self)

        self.name = os.path.basename(name)
        self.parent = parent
        
        if self.parent is not None:
            #
            # If we have a parent, tell it about
            # ourself and use the basename of
            # our name as the canonical name.
            #
            self.parent.addSubNode(self)
            self.canonical_name = self.name
        else:
            #
            # We have no parent, so use our full
            # name as the canonical name.
            #
            self.canonical_name = name
        
        trace.write('self.name=%s' % self.name, outputLevel=TRACE_LEVEL)

        trace.outof(outputLevel=TRACE_LEVEL)
        return

    def __repr__(self):
        #base_str = UserDict.UserDict.__repr__(self)
        base_str = ''
        return '<%s %s: %s>' % (self.__class__.__name__, self.getName(), base_str)

    def __len__(self):
        """Define this to always return 1, so checks like 'if node' work properly.
        """
        return 1

    #
    # Data retrieval methods
    #
    
    def getMimeType(self):
        """Returns the (mimetype, encoding) setting for this node.
        """
        trace.into('PackageTreeNode', 'getMimeType',
                   name=self.name,
                   outputLevel=TRACE_LEVEL,
                   )

        input_filename = self.getInputFilename()
        mimetype, encoding = getMimeType(input_filename)
        
        trace.outof(mimetype, outputLevel=TRACE_LEVEL)
        return (mimetype, encoding)

    def getName(self):
        """Returns the name of this tree node.
        """
        return self.name

    def getCanonicalName(self):
        """Returns the canonical, full, name of the this tree node.
        """
        return self.canonical_name
    
    def getInputFilename(self):
        """Returns the original input filename that created the node.
        """
        trace.into('PackageTree', 'getInputFilename',
                   outputLevel=TRACE_LEVEL)
        
        node_path = self.getPath(1)
        trace.writeVar(node_path=node_path, outputLevel=TRACE_LEVEL)
        filename = apply(os.path.join, node_path)
        trace.writeVar(filename=filename, outputLevel=TRACE_LEVEL)

        trace.outof(filename, outputLevel=TRACE_LEVEL)
        return filename

    def getRelativeFilename(self):
        """Returns the filename relative to the root of the input area.
        """
        trace.into('PackageTree', 'getRelativeFilename',
                   outputLevel=TRACE_LEVEL)
        
        node_path = self.getPath()
        trace.writeVar(node_path=node_path,
                       outputLevel=TRACE_LEVEL)
        filename = apply(os.path.join, node_path)
        trace.writeVar(filename=filename,
                       outputLevel=TRACE_LEVEL)

        trace.outof(filename, outputLevel=TRACE_LEVEL)
        return filename

    def getDocStringAndFormat(self):
        """Returns a tuple containing the actual documentation string
        and the format of that docstring as understood by the
        docstring converters plugins.
        """
        raise NotImplementedError('getDocStringAndFormat')

    def getSummaryAndFormat(self):
        """Returns a tuple containing a one line summary of the
        documentation for the node and the format of that
        string as understood by the docstring converter plugins.
        """
        raise NotImplementedError('getSummaryAndFormat')

    def getOneLiner(self):
        return self.getSummaryAndFormat()[0]

    def getImportData(self):
        "Returns a list of the symbols which are imported."
        return []
        

    #
    # Tree methods
    #
    
    def getParent(self):
        """Returns the parent node for this tree.

        If there is no parent (root of the tree), returns None.
        """
        return self.parent

    def getPath(self, useCanonicalName=0):
        """Return the path from the root to this node.

        Returns a tuple of node names, beginning with the root node
        and ending with this node.
        """
        trace.into('PackageTree', 'getPath',
                   useCanonicalName=useCanonicalName,
                   outputLevel=TRACE_LEVEL+1,
                   )
        
        parent = self.getParent()
        trace.writeVar(parent=parent,
                       outputLevel=TRACE_LEVEL+1,
                       )
        if parent:
            parent_path = parent.getPath(useCanonicalName=useCanonicalName)
        else:
            parent_path = ()

        trace.writeVar(parent_path=parent_path,
                       outputLevel=TRACE_LEVEL+1,
                       )

        if useCanonicalName:
            name = self.getCanonicalName()
        else:
            name = self.getName()
            
        path = parent_path + (name,)

        trace.outof(path,
                    outputLevel=TRACE_LEVEL+1,
                    )
        return path

    def getPathToNode(self, otherNode):
        """Returns a sequence of nodes to be traversed to reach the otherNode.

        The sequence assumes that traversal begins at the current node.
        A '..' indicates moving up to the parent one level.
        """
        trace.into('PackageTree', 'getPathToNode',
                   otherNode=otherNode.getName(),
                   outputLevel=TRACE_LEVEL,
                   )
        
        my_path = self.getPath()
        other_path = otherNode.getPath()
        if my_path == other_path:
            trace.outof((), outputLevel=TRACE_LEVEL)
            return ()

        #
        # Strip the top parts of the paths which match.
        #
        while my_path and other_path and my_path[0] == other_path[0]:
            trace.write('Removing %s from both paths' % my_path[0],
                        outputLevel=TRACE_LEVEL)
            my_path = my_path[1:]
            other_path = other_path[1:]

        trace.writeVar(my_path=my_path,
                       other_path=other_path,
                       outputLevel=TRACE_LEVEL,
                       )
            
        if not other_path:
            #
            # Special Case: I am a child of the other node.
            #
            trace.write('source is child of dest',
                        outputLevel=TRACE_LEVEL)
            if self.getMimeType()[0] == 'application/x-directory':
                is_dir = 1
            else:
                is_dir = 0

            trace.writeVar(is_dir=is_dir,
                           outputLevel=TRACE_LEVEL)
            going_up = ('..',) * (len(my_path) + is_dir)
            other_path = (otherNode.getName(),)
        
        else:
            #
            # Either a parent or off in another branch of the
            # tree.
            #
            if self.getMimeType()[0] == 'application/x-directory':
                is_file = 0
            else:
                is_file = 1
                
            going_up = ('..',) * (len(my_path) - is_file)

        #
        # Go up to a common point in the tree,
        # and then back down to the other node.
        #
        relative_path = going_up + other_path

        trace.outof(relative_path, outputLevel=TRACE_LEVEL)
        return relative_path

    def findNodeFromDottedName(self, dottedNodeName,
                               tryParent=1,
                               tryModuleExtensions=1,
                               ):
        """Find the node referenced by the dotted name given.

        The dottedNodeName 'happydoclib.scanner' retuns the node for
        this module.  If the named node cannot be found, the return
        value is None.
        """
        trace_level=TRACE_LEVEL
        trace.into('PackageTree', 'findNodeFromDottedName',
                   dottedNodeName=dottedNodeName,
                   outputLevel=trace_level,
                   start=self.getName(),
                   )
        
        name_parts = dottedNodeName.split('.')
        name = name_parts[0]

        trace.write('name=%s' % name,
                    outputLevel=trace_level,
                    )
        trace.writeVar(name=name,
                       outputLevel=trace_level,
                       )

        named_node = None

        #
        # Is someone looking for us?
        #
        if (named_node is None):
            if (name == self.getName()):
                trace.write('Matched ourself',
                            outputLevel=trace_level,
                            )
                named_node = self

        if (named_node is None):
            trace.write('Checking %s as child' % name,
                        outputLevel=trace_level,
                        )
            named_node = self.get(name)
            
        if (named_node is None) and tryModuleExtensions:
            trace.write('Checking %s.py as child' % name,
                        outputLevel=trace_level,
                        )
            named_node = self.get('%s.py' % name)

        if (named_node is None) and tryParent:
            #
            # Try the parent with the whole name
            #
            parent = self.getParent()
            if parent:
                trace.write('Checking for %s in parent' % name,
                            outputLevel=trace_level,
                            )
                named_node = parent.findNodeFromDottedName(dottedNodeName)

        #
        # Do we need to process the remainder of the original name?
        #
        if named_node and (len(name_parts) > 1):
            remainder = '.'.join(name_parts[1:])
            trace.write('Handling remainder (%s)' % remainder,
                        outputLevel=trace_level,
                        )
            named_node = named_node.findNodeFromDottedName(remainder,
                                                           tryParent=0)

        if named_node is not None:
            trace.outof(named_node.getName(),
                        outputLevel=trace_level,
                        )
        else:
            trace.outof(outputLevel=trace_level)
        return named_node

    def addSubNode(self, node):
        """Insert a child node under this node.

        Create a new PackageTree node, set its parent to be ourself,
        and save it as one of our children.
        """
        self[node.getName()] = node
        return node

    def getSubNodes(self, mimetypes=[]):
        """Returns the children of this node.

        If mimetype is not none, returns only the children with that
        mimetype.
        """
        if not mimetypes:
            return self.values()
        else:
            if not hasattr(self, 'grouped_children'):
                self.grouped_children = {}
                for node in self.values():
                    node_mimetype, node_encoding = node.getMimeType()
                    group = self.grouped_children.setdefault(node_mimetype, [])
                    group.append(node)

            subnodes = []
            for mimetype in mimetypes:
                subnodes += self.grouped_children.get(mimetype, [])

            subnodes.sort()
            return subnodes

    def __cmp__(self, other):
        """Comparison by name for sorting.
        The name check is case insensitive.
        """
        return cmp(self.getName().lower(), other)

    def walk(self, callback):
        """Walk the PackageTree, calling the callback at each node.
        """
        callback(self)
        for child in self.values():
            child.walk(callback)
        return


    
class CodeObjectTree(PackageTree):
    """Represents a code object to be documented.
    """

    MIMETYPE = 'application/x-code'
    
    def __init__(self, parent, name):
        """Construct a CodeObjectTree.
        """
        trace.into('CodeObjectTree', '__init__',
                   name=name,
                   outputLevel=TRACE_LEVEL,
                   )
        PackageTree.__init__(self, parent, name)
        self.code_info = self._getCodeInfo()
        trace.write(self.getMimeType()[0], outputLevel=TRACE_LEVEL)
        trace.outof(outputLevel=TRACE_LEVEL)
        return

    def getMimeType(self):
        return (self.MIMETYPE, None)

    def getInputFilename(self):
        """Returns the input filename of the parent node.
        """
        return self.getParent().getInputFilename()

    def getRelativeFilename(self):
        """Returns the filename of the parent node.
        """
        return self.getParent().getRelativeFilename()

    def getDocStringAndFormat(self):
        """Returns the docstring of the code object, and the format of that data.
        """
        return self.code_info.getDocStringAndFormat()

    def getSummaryAndFormat(self):
        """Returns a tuple containing a one line summary of the
        documentation for the node and the format of that
        string as understood by the docstring converter plugins.
        """
        return self.code_info.getSummaryAndFormat()
    

class FunctionTree(CodeObjectTree):
    """Represents a function in the package tree.
    """
    MIMETYPE = 'application/x-function'

    def _getCodeInfo(self):
        return self.getParent().module_info.getFunctionInfo(self.name)

class MethodTree(FunctionTree):
    """Represents a method in the package tree.
    """

    def _getCodeInfo(self):
        return self.getParent().code_info.getMethodInfo(self.name)
    
class ClassTree(CodeObjectTree):
    """Represent a class in the package tree.
    """

    MIMETYPE = 'application/x-class'

    def __init__(self, parent, name):
        trace.into('ClassTree', '__init__',
                   name=name,
                   outputLevel=TRACE_LEVEL,
                   )
        CodeObjectTree.__init__(self, parent, name)

        for method_name in self.code_info.getMethodNames():
            method_node = MethodTree(self, method_name)
            
        trace.outof(outputLevel=TRACE_LEVEL)
        return
    
    def _getCodeInfo(self):
        return self.getParent().module_info.getClassInfo(self.name)
    
    def getRelativeFilename(self):
        """Classes are written to their own file.
        """
        return PackageTree.getRelativeFilename(self)

#    def getRelativeFilename(self):
#        """Returns the filename of this node.
#        """
#        parent_filename = self.getParent().getRelativeFilename()
#        parent_filename, ext = os.path.splitext(parent_filename)
#        my_filename = os.path.join(parent_filename, self.getName())
#        return my_filename
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.