# Display all scripting code of window and template components

**URL:** <https://forum.inductiveautomation.com/t/display-all-scripting-code-of-window-and-template-components/20262>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [October 18, 2018, 7:19pm UTC](https://forum.inductiveautomation.com/t/display-all-scripting-code-of-window-and-template-components/20262 "2018-10-18T19:19:39Z")\
**Posts on this page:** 1\
**Showing post:** 2

<div class="post-metadata">

**Author:** ![raymond1982](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/raymond1982/32/6490_2.png) [@raymond1982](https://forum.inductiveautomation.com/u/raymond1982)\
**Post date:** [October 18, 2018, 7:47pm UTC](https://forum.inductiveautomation.com/t/display-all-scripting-code-of-window-and-template-components/20262/2 "2018-10-18T19:47:29Z")

</div>

Step 1: Get the context. I think this is familiar.

> [@Programatically search through templates?](http://forum.inductiveautomation.com/t/programatically-search-through-templates/19862/8):
>
> yes. This may require some explanation. Instead of using an event object i create a Jframe and grab the projects highest most frame reference and get it that way… I work in console a lot too and this helps. This is a singleton class which makes it nice. Load it at startup and dont worry about getting it again.Heavily unsupported. from system.util import CLIENT\_FLAG, DESIGNER\_FLAG from javax.swing import JFrame from java.awt.event import WindowEvent try: from com.inductiveautomation.ignition.d…

If the context cant be located in the script console you may have a flag that is odd.  
print the system.util.getSystemFlags() and add the resulting integer to [DESIGNER\_FLAG, 3] list.

```auto
current_flag = system.util.getSystemFlags()
ctx = self.resolveDesignerContext
# If False assumes the client context.
if current_flag not in [DESIGNER_FLAG, 3]:

```

After ensuring you have the context this should work. Update the path to your context and have fun with the joke.

Step 2:

```auto
from com.inductiveautomation.factorypmi.application.binding.action import ActionAdapter

class ScriptFinder:
	
	def __init__ (self, context):
		
		self.context = context
		if not hasattr(self.context, 'getProject'):
			raise Exception(self.getInvalidContextError(context))
	
	def getProjectResources(self):
		"""Return all project Resources."""
		return self.context.getProject().getResources()
		
	def getInvalidResourceTypeError(self, resource_type):
		"""Return formatted error message."""
		return 'Invalid Resource Type "%s". Options are: %s || %s.' % (
			resource_type, self.getWindowResourceType(), self.getTemplateResourceType())

	def getInvalidContextError(self, context):
		"""Return formatted error message."""
		return 'Invalid Context Reference "%s". Hint Context must support getProject method' % str(type(context))
		
	def objectSearch(self, fpmiObject, array):
		"""
		NOTES: 
		: This method takes an JComponent
		: and an array reference it will recursivley 
		: walk the component chain accumulating members until 
		: reaching the last container.
		
		Arg(s):
		: [fpmiObject] DataType: JComponent
		:	Example: Jframe, Jdialog, FMPI Root Container,
		: [array] DataType: list
		:	Example: []
		"""
		try:
			for component in fpmiObject.getComponents():
				array.append(component)
				self.objectSearch(component, array)
		except AttributeError:
			return

	def getAllComponentsForFpmiObject(self, fpmiObject):
		"""
		NOTES: 
		: Method takes a top level jcomponent and calls the
		: getComponents method. If the result is an AttributeError
		: the array is returned. If there are results both the array
		: reference and the component are passed to a recursive function
		: that will go throught the component chain.
		
		Arg(s):
		: [fpmiObject] DataType: JComponent
		: Example: Jframe, Jdialog, FMPI Root Container,
		"""
		components_array = []
		try:
			for component in fpmiObject.getComponents():
				components_array.append(component)
				self.objectSearch(component, components_array)
		except AttributeError:
			pass		
		return components_array
	
	def getProjectResourcesByType(self, resource_type):
		"""
		NOTES:
		: Filter resource array on type.
		Arg(s):
		: [resource_type] DataType: String
		:	Example: "window", "component-template"
		"""
		return [
			resource for resource in self.getProjectResources() 
			if resource.getResourceType() == resource_type
		]
		
	def getWindowResourceType(self):
		"""Returns windows resource type."""
		return 'window'
	
	def getTemplateResourceType(self):
		"""Returns template resource type."""
		return 'component-template'	
	
	
	def getSerializedReferenceFromResource(self, resource_type):
		"""
		NOTES:
		: Returns a reusable function for the deserialization of 
		: the requested types. Reduces process overhead for iterative
		: resource assessment.
		
		Arg(s):
		: [resource_type] DataType: String
		: Example: "window", "component-template"
		"""
	
		deserializer = self.context.createDeserializer()
		deserialize = deserializer.deserialize
		
		def windowInner(resource):
			"""
			NOTES:
			: Inner Function that supports deserialization of window 
			: resources. The window root objects support a different method than
			: templates for retrieving the bytesArray.
			
			Arg(s)
			: [resource] DataType: <type 'com.inductiveautomation.ignition.common.project.ProjectResource'>
			"""
			code = deserialize(resource.getData()).getRootObjects()[0].getSerializedCode()
			return deserialize(code).getRootObjects()[0]
		
		def templateInner(resource):
			"""
			NOTES:
			: Inner Function that supports deserialization of template
			: resources. The template root objects support a different method than
			: templates for retrieving the bytesArray.
			
			Arg(s)
			: [resource] DataType: <type 'com.inductiveautomation.ignition.common.project.ProjectResource'>
			:
			"""
			code = deserialize(resource.getData()).getRootObjects()[0].getSerializedBytes()
			return deserialize(code).getRootObjects()[0]
		
		if resource_type == self.getWindowResourceType():
			return windowInner
		elif resource_type == self.getTemplateResourceType():
			return templateInner
		raise Exception(self.getInvalidResourceTypeError(resource_type))
			
	
	def getDeSerializedResources(self, resource_type, resource_array):
		"""
		NOTES:
		: Return an array of deserialized project resoures.
		
		Arg(s)
		: [resource_type] DataType: String
		: Example: "window", "component-template"
		: [resource_array] DataType: list
		: Example: []
		"""
		deserializer = self.getSerializedReferenceFromResource(resource_type)
		return [deserializer(resource) for resource in resource_array]
	
	
	def getComponentAdapterGetter(self, resource):
		"""
		NOTES:
		: Returns an uncalled method for use in iteration.
		: This method gets all adapteres associated for the
		: component passed in.
		
		Arg(s)
		: [resource] DataType: <type 'com.inductiveautomation.ignition.common.project.ProjectResource'>
		:  
		"""		
		return resource.getInteractionController().getAllAdaptersForTarget
	
	
	def getValidResourceType(self):
		"""Returns array of valid resource types."""
		return [self.getWindowResourceType(), self.getTemplateResourceType()]
	
	def isResourceTypeValid(self, resource_type):
		"""Checks resource type for validity."""
		return resource_type in self.getValidResourceType()
	
	def getObjectName(self, resource):
		"""Return object name."""
		return str(resource.getTitle() if hasattr(resource, 'getTitle') else resource.getName())
		
	def getActionAdatpersforComponent(self, resource, component):
		"""Returns filtered array of Action Adapters for component."""
		adapterGetter = self.getComponentAdapterGetter(resource)
		return [adapter for adapter in adapterGetter(component) if isinstance(adapter, ActionAdapter)]
	
	
	def getJythonCodeForResourceComponents(self, resource_type):
		"""
		NOTES:
		: Returns a dictionary of resource: {components: {code: ''}}.
		: Process acquires resources of specified type and iterates
		: over all components action adapters.
		
		Arg(s)
		: [resource_type] DataType: String
		: Example: "window", "component-template"
		"""	
		# Test validity of type.
		if self.isResourceTypeValid(resource_type):
			resource_component_code_map = {}
			#Acquire resource data for type.
			resources = self.getProjectResourcesByType(resource_type)
			# Iterate through deserialized resources.
			for resource in self.getDeSerializedResources(resource_type, resources):
				resource_name = self.getObjectName(resource)
				# Get all components.
				components = self.getAllComponentsForFpmiObject(resource)
				if components:
					resource_component_code_map[resource_name] = {}
					#Iterate over component.
					for component in components:
						component_name = self.getObjectName(component)
						# Get adapters for component and iterate filtering on action adapters.
						for adapter in self.getActionAdatpersforComponent(resource, component):
							# Create entry in dictionary if not present.
							if component_name not in resource_component_code_map[resource_name]:
								resource_component_code_map[resource_name][component_name] = {}
							# Get code from action adapter.
							code = adapter.getJythonCode()
							# Get component method associated with the code.
							method_name = adapter.getMethodDescriptor().getName()
							# Update resource map.
							resource_component_code_map[resource_name][component_name][method_name] = code
							
			return resource_component_code_map
		
		raise Exception(self.getInvalidResourceTypeError(resource_type))
		return {}

	def getAllWindowsAllComponentsJythonCode(self):
		""" Returns dictionary of window resource: {components: {code: ''}}."""
		return self.getJythonCodeForResourceComponents(self.getWindowResourceType())

	def getAllTemplatesAllComponentsJythonCode(self):
		""" Returns dictionary of template resource: {components: {code: ''}}."""
		return self.getJythonCodeForResourceComponents(self.getTemplateResourceType())

	def prettyPrint(self, output):
		print system.util.jsonEncode(output, 4)

context = project.Resources.Context.getContext() # <- this must be correct
sf = ScriptFinder(context)

sf.prettyPrint(sf.getAllWindowsAllComponentsJythonCode())

sf.prettyPrint(sf.getAllTemplatesAllComponentsJythonCode())

```

---

_[View the full topic](https://forum.inductiveautomation.com/t/display-all-scripting-code-of-window-and-template-components/20262)._
