def nodeAsJSON(self, node):
        """
		node    = Node based on which the pattern is to be created
		RETURN  = JSON object containing patterns for all node attributes

		Method to walk through the list of attributes in a node and return the
		supported types out in a JSON attribute pattern format. The returned
		object can then be written out to a file or processed directly as a 
		JSON attribute pattern.

		There will be up to three attribute patterns specified in the object,
		one for each of static, dynamic, and extension attributes. Each of the
		patterns is only created if there is at least one attribute of that type.

		The names of the patterns for a node named "NODE" will be:
			dynamic_NODE
			static_NODE
			extension_NODE
		You really don't need me to explain which is which do you?
		"""
        self.node = node  # Need this local for getting attribute info
        self.dgNode = omAPI.MSelectionList().add(node).getDependNode(0)
        jsonDebug('Getting node information from %s' % str(self.dgNode))
        patternList = []

        try:
            dynamicAttributes = cmds.listAttr(node, userDefined=True)
            extensionAttributes = cmds.listAttr(node, extension=True)
            allAttributes = cmds.listAttr(node)
            staticAttributes = [
                attr for attr in allAttributes
                if not attr in extensionAttributes
                and not attr in dynamicAttributes
            ]
            #----------------------------------------------------------------------
            # Add the static attribute pattern to the string if there are any
            newPattern = self.attributeListAsJSON("static_%s" % node,
                                                  staticAttributes)
            if newPattern != None:
                patternList.append(newPattern)

            #----------------------------------------------------------------------
            # Add the dynamic attribute pattern to the string if there are any
            newPattern = self.attributeListAsJSON("dynamic_%s" % node,
                                                  dynamicAttributes)
            if newPattern != None:
                patternList.append(newPattern)

            #----------------------------------------------------------------------
            # Add the extension attribute pattern to the string if there are any
            newPattern = self.attributeListAsJSON("extension_%s" % node,
                                                  extensionAttributes)
            if newPattern != None:
                patternList.append(newPattern)

        except Exception, e:
            print 'ERR: Failed pattern creation on node %s (%s)' % (node,
                                                                    str(e))
	def nodeAsJSON(self, node):
		"""
		node    = Node based on which the pattern is to be created
		RETURN  = JSON object containing patterns for all node attributes

		Method to walk through the list of attributes in a node and return the
		supported types out in a JSON attribute pattern format. The returned
		object can then be written out to a file or processed directly as a 
		JSON attribute pattern.

		There will be up to three attribute patterns specified in the object,
		one for each of static, dynamic, and extension attributes. Each of the
		patterns is only created if there is at least one attribute of that type.

		The names of the patterns for a node named "NODE" will be:
			dynamic_NODE
			static_NODE
			extension_NODE
		You really don't need me to explain which is which do you?
		"""
		self.node = node	# Need this local for getting attribute info
		self.dgNode = omAPI.MSelectionList().add(node).getDependNode(0)
		jsonDebug( 'Getting node information from %s' % str(self.dgNode) )
		patternList = []

		try:
			dynamicAttributes = cmds.listAttr( node, userDefined=True )
			extensionAttributes = cmds.listAttr( node, extension=True )
			allAttributes = cmds.listAttr( node )
			staticAttributes = [attr for attr in allAttributes if not attr in extensionAttributes and not attr in dynamicAttributes]
			#----------------------------------------------------------------------
			# Add the static attribute pattern to the string if there are any
			newPattern = self.attributeListAsJSON( "static_%s" % node, staticAttributes )
			if newPattern != None:
				patternList.append( newPattern )

			#----------------------------------------------------------------------
			# Add the dynamic attribute pattern to the string if there are any
			newPattern = self.attributeListAsJSON( "dynamic_%s" % node, dynamicAttributes )
			if newPattern != None:
				patternList.append( newPattern )

			#----------------------------------------------------------------------
			# Add the extension attribute pattern to the string if there are any
			newPattern = self.attributeListAsJSON( "extension_%s" % node, extensionAttributes )
			if newPattern != None:
				patternList.append( newPattern )

		except Exception, e:
			print 'ERR: Failed pattern creation on node %s (%s)' % (node, str(e))
    def attributeAsJSON(self, attr):
        """
		Convert the attribute into its JSON attribute pattern equivalent.
			attr   = Attribute belonging to the pattern
			RETURN = JSON object representing the attribute
		"""
        jsonDebug('attributeAsJSON(%s)' % attr)
        jsonAttr = {}
        jsonAttr['name'] = attr

        shortName = cmds.attributeQuery(attr, node=self.node, shortName=True)
        # No need to write it if they two names are the same
        if shortName != attr: jsonAttr['shortName'] = shortName

        niceName = cmds.attributeQuery(attr, node=self.node, niceName=True)
        jsonAttr['niceName'] = niceName

        attributeType = attributeTypeName(self.node, attr)
        jsonAttr['attributeType'] = attributeType
        jsonDebug('... type %s' % attributeType)

        categories = cmds.attributeQuery(attr, node=self.node, categories=True)
        if categories != None and len(categories) > 0:
            jsonAttr['categories'] = categories

        # Some flags default to false, some default to true, some are
        # code-dependent. Force setting of the ones who have changed
        # from their defaults, or whose defaults are unknown.
        #
        # Keep the list alphabetical for convenience
        flagList = []
        if cmds.attributeQuery(attr, node=self.node, affectsAppearance=True):
            flagList.append('affectsAppearance')
        if cmds.attributeQuery(attr, node=self.node, affectsWorldspace=True):
            flagList.append('affectsWorldspace')
        if not cmds.attributeQuery(attr, node=self.node,
                                   cachedInternally=True):
            flagList.append('!cached')
        if not cmds.attributeQuery(attr, node=self.node, writable=True):
            flagList.append('!canConnectAsDst')
        isReadable = True
        if not cmds.attributeQuery(attr, node=self.node, readable=True):
            isReadable = False
            flagList.append('!canConnectAsSrc')
        if cmds.attributeQuery(attr, node=self.node, multi=True):
            flagList.append('array')
            # You can't set the indexMatters flag unless the attribute is an
            # unreadable array attribute. (It might be set otherwise, but just
            # by accident and the API doesn't support setting it incorrectly.)
            if cmds.attributeQuery(attr, node=self.node,
                                   indexMatters=True) and not isReadable:
                flagList.append('indexMatters')
        if cmds.attributeQuery(attr, node=self.node, channelBox=True):
            flagList.append('channelBox')
        if not cmds.attributeQuery(attr, node=self.node, connectable=True):
            flagList.append('!connectable')
        if cmds.attributeQuery(attr, node=self.node, hidden=True):
            flagList.append('hidden')
        if cmds.attributeQuery(attr, node=self.node, indeterminant=True):
            flagList.append('indeterminant')
        if cmds.attributeQuery(attr, node=self.node, internalSet=True):
            flagList.append('internal')
        if cmds.attributeQuery(attr, node=self.node, keyable=True):
            flagList.append('keyable')
        else:
            flagList.append('!keyable')
        if cmds.attributeQuery(attr, node=self.node, renderSource=True):
            flagList.append('renderSource')
        if not cmds.attributeQuery(attr, node=self.node, storable=True):
            flagList.append('!storable')
        if cmds.attributeQuery(attr, node=self.node, usedAsColor=True):
            flagList.append('usedAsColor')
        if cmds.attributeQuery(attr, node=self.node, usedAsFilename=True):
            flagList.append('usedAsFilename')
        if cmds.attributeQuery(attr, node=self.node, usesMultiBuilder=True):
            flagList.append('usesArrayDataBuilder')
        if cmds.attributeQuery(attr, node=self.node, worldspace=True):
            flagList.append('worldspace')

        # Write out the flag collection
        if len(flagList) > 0:
            jsonAttr['flags'] = flagList

        # Get attribute-type specific JSON parameters
        extraInfo = None
        if attributeType == 'enum':
            jsonDebug('... decoding enum attribute parameters')
            extraInfo = self.enumAttributeAsJSON(attr)
        elif attributeType in JsonKeys.kNumericTypes:
            jsonDebug('... decoding numeric attribute parameters')
            extraInfo = self.numericAttributeAsJSON(attr)
        elif attributeType in JsonKeys.kTypeMatrix:
            jsonDebug('... decoding matrix attribute parameters')
            extraInfo = self.matrixAttributeAsJSON(attr)
        elif attributeType == 'string':
            jsonDebug('... decoding string attribute parameters')
            extraInfo = self.stringAttributeAsJSON(attr)
        elif attributeType == 'message':
            jsonDebug('... decoding message attribute parameters')
        elif attributeType == 'compound':
            jsonDebug('... decoding compound attribute parameters')
            extraInfo = self.compoundAttributeAsJSON(attr)
        elif attributeType == 'lightData':
            jsonDebug('... decoding lightData attribute parameters')
            extraInfo = self.lightDataAttributeAsJSON(attr)
        elif attributeType == 'typed':
            jsonDebug('... decoding typed attribute parameters')
            extraInfo = self.typedAttributeAsJSON(attr)

        if extraInfo != None:
            for extraKey in extraInfo:
                jsonAttr[extraKey] = extraInfo[extraKey]

        return jsonAttr
	def attributeAsJSON(self, attr):
		"""
		Convert the attribute into its JSON attribute pattern equivalent.
			attr   = Attribute belonging to the pattern
			RETURN = JSON object representing the attribute
		"""
		jsonDebug( 'attributeAsJSON(%s)' % attr)
		jsonAttr = {}
		jsonAttr['name'] = attr
	
		shortName = cmds.attributeQuery( attr, node=self.node, shortName=True )
		# No need to write it if they two names are the same
		if shortName != attr: jsonAttr['shortName'] = shortName
	
		niceName = cmds.attributeQuery( attr, node=self.node, niceName=True )
		jsonAttr['niceName'] = niceName
	
		attributeType = attributeTypeName(self.node, attr)
		jsonAttr['attributeType'] = attributeType
		jsonDebug( '... type %s' % attributeType )
	
		categories = cmds.attributeQuery( attr, node=self.node, categories=True )
		if categories != None and len(categories) > 0:
			jsonAttr['categories'] = categories
	
		# Some flags default to false, some default to true, some are
		# code-dependent. Force setting of the ones who have changed
		# from their defaults, or whose defaults are unknown.
		#
		# Keep the list alphabetical for convenience
		flagList = []
		if cmds.attributeQuery( attr, node=self.node, affectsAppearance=True ):
			flagList.append( 'affectsAppearance' )
		if cmds.attributeQuery( attr, node=self.node, affectsWorldspace=True ):
			flagList.append( 'affectsWorldspace' )
		if not cmds.attributeQuery( attr, node=self.node, cachedInternally=True ):
			flagList.append( '!cached' )
		if not cmds.attributeQuery( attr, node=self.node, writable=True ):
			flagList.append( '!canConnectAsDst' )
		isReadable = True
		if not cmds.attributeQuery( attr, node=self.node, readable=True ):
			isReadable = False
			flagList.append( '!canConnectAsSrc' )
		if cmds.attributeQuery( attr, node=self.node, multi=True ):
			flagList.append( 'array' )
			# You can't set the indexMatters flag unless the attribute is an
			# unreadable array attribute. (It might be set otherwise, but just
			# by accident and the API doesn't support setting it incorrectly.)
			if cmds.attributeQuery( attr, node=self.node, indexMatters=True ) and not isReadable:
				flagList.append( 'indexMatters' )
		if cmds.attributeQuery( attr, node=self.node, channelBox=True ):
			flagList.append( 'channelBox' )
		if not cmds.attributeQuery( attr, node=self.node, connectable=True ):
			flagList.append( '!connectable' )
		if cmds.attributeQuery( attr, node=self.node, hidden=True ):
			flagList.append( 'hidden' )
		if cmds.attributeQuery( attr, node=self.node, indeterminant=True ):
			flagList.append( 'indeterminant' )
		if cmds.attributeQuery( attr, node=self.node, internalSet=True ):
			flagList.append( 'internal' )
		if cmds.attributeQuery( attr, node=self.node, keyable=True ):
			flagList.append( 'keyable' )
		else:
			flagList.append( '!keyable' )
		if cmds.attributeQuery( attr, node=self.node, renderSource=True ):
			flagList.append( 'renderSource' )
		if not cmds.attributeQuery( attr, node=self.node, storable=True ):
			flagList.append( '!storable' )
		if cmds.attributeQuery( attr, node=self.node, usedAsColor=True ):
			flagList.append( 'usedAsColor' )
		if cmds.attributeQuery( attr, node=self.node, usedAsFilename=True ):
			flagList.append( 'usedAsFilename' )
		if cmds.attributeQuery( attr, node=self.node, usesMultiBuilder=True ):
			flagList.append( 'usesArrayDataBuilder' )
		if cmds.attributeQuery( attr, node=self.node, worldspace=True ):
			flagList.append( 'worldspace' )
	
		# Write out the flag collection
		if len(flagList) > 0:
			jsonAttr['flags'] = flagList

		# Get attribute-type specific JSON parameters
		extraInfo = None
		if attributeType == 'enum':
			jsonDebug( '... decoding enum attribute parameters' )
			extraInfo = self.enumAttributeAsJSON(attr )
		elif attributeType in JsonKeys.kNumericTypes:
			jsonDebug( '... decoding numeric attribute parameters' )
			extraInfo = self.numericAttributeAsJSON(attr )
		elif attributeType in JsonKeys.kTypeMatrix:
			jsonDebug( '... decoding matrix attribute parameters' )
			extraInfo = self.matrixAttributeAsJSON(attr )
		elif attributeType == 'string':
			jsonDebug( '... decoding string attribute parameters' )
			extraInfo = self.stringAttributeAsJSON(attr )
		elif attributeType == 'message':
			jsonDebug( '... decoding message attribute parameters' )
		elif attributeType == 'compound':
			jsonDebug( '... decoding compound attribute parameters' )
			extraInfo = self.compoundAttributeAsJSON(attr )
		elif attributeType == 'lightData':
			jsonDebug( '... decoding lightData attribute parameters' )
			extraInfo = self.lightDataAttributeAsJSON(attr )
		elif attributeType == 'typed':
			jsonDebug( '... decoding typed attribute parameters' )
			extraInfo = self.typedAttributeAsJSON(attr )

		if extraInfo != None:
			for extraKey in extraInfo:
				jsonAttr[extraKey] = extraInfo[extraKey]
	
		return jsonAttr