Advanced Customization > Windchill Adapter > Custom Windchill Adapter Webjects > Type-Based Webject Delegate Example
  
Type-Based Webject Delegate Example
With the “Hello, World!” example, the class or type of the target object was not relevant except for webject delegate lookup, because the webject delegate did not perform actions upon or query for a target object or objects.
This example shows how to create a type-based webject delegate that is specific to the Windchill type wt.part.WTPart.
The basic operation of the Fetch-PartRelations webject is to search for or fetch instances of wt.part.WTPart. It also resolves some immediate relationships between that part and other parts and documents, returning the part along with the related objects as nested Info*Engine elements.
Step 1: Write the new webject delegate
Since the Fetch-PartRelations webject is based on a lot of the same basic functionality as a webject such Query-Objects, this webject extends com.ptc.core.adapter.server.impl.ObjectWebject.
By extending ObjectWebject, the Fetch-PartRelations webject automatically inherits most core OBJ webject parameters (for instance: TYPE/WHERE, OBJECT_REF, REFERENCE_DELIMITER, CONTAINER_REF, and so on). Which parameters are actually used by the webject are based on what shared convenience methods it calls.
The first thing the webject does is call the preset(Task) method, which causes the parent classes to validate the incoming webject and gather common parameters.
The webject later uses the getTargetTypeInstances() method to perform the base search and fetch (as appropriate per the TYPE/WHERE and OBJECT_REF and other parameters supplied).
As a result, it uses most of the parameters associated with performing a search. Despite the fact that the webject uses these parameters, it does not need to explicitly perform any validation of them itself since that is handled by the parent classes.
The webject source contains many descriptive comments to clarify how it works. The webject source can be found on your installation at:
<Windchill>/prog_examples/adapter/windchill/customwebjects/src
* 
The webject uses an inherited instance variable named adapterLogger. This instance variable is a reference to a log4j logger that is used by Windchill adapter webjects.
By reusing the inherited log4j loggers, your adapter webjects can inherit existing log4j Windchill adapter configurations without needing to invent your own logging mechanism. See the javadoc for AbstractWebject to see what other loggers are available for you to use implicitly by virtue of extending a Windchill adapter base class.
Step 2: Inform the Windchill adapter of the new webject
In order for the Windchill adapter to be able to recognize the new webject delegate, it must be registered in wt.adapter.delegates.properties. Add the following line:
FETCHPARTRELATIONS.WCTYPE|
wt.part.WTPart=ext.example.FetchPartRelationsWebjectDelegate
This entry performs the following functions:
Specifies the name of the new webject delegate, FETCHPARTRELATIONS.
Indicates that the webject is valid for target objects of class or type wt.part.WTPart.
Indicates which class contains the invoke() method that should be executed.
Note that the property definition attaches this webject delegate directly to wt.part.WTPart rather than to a more inclusive class such as java.lang.Object. This is done because this webject is specific to instances of wt.part.WTPart and cannot be called for other types.
If someone were to attempt to call this webject with a type other than wt.part.WTPart (or one of its subclasses) the adapter would fail to find the webject delegate and throw the appropriate exception. Attaching it to the wt.part.WTPart class implicitly avoids the obscure errors that would result from trying to apply logic intended for parts to other business object types.
You must restart the method server for this change to be recognized.
Step 3: Create an XML task
Now, create an XML task document containing a Fetch-PartRelations webject. You must create the task within the tasks directory that was set up for your Windchill server. The following is an example Fetch-PartRelations.xml:
* 
The task source can be found in your installation at <Windchill>/prog_examples/adapter/windchill/customwebjects/tasks
<%@page language="java"%>
<%@taglib uri="http://www.ptc.com/infoengine/taglib/core"
prefix="ie"%>

<!--com.infoengine.soap.rpc.def
The following fetches or searches for base parts and then expands references to related objects as requested by input:
@param string[] object_ref One or more object references of
parts to fetch.
@param string type The base type
(must be wt.part.WTPart or a subclass).
@param string where If searching for parts the where clause
used to select part/s.
@param string[] what What relations to return
(PARENTS,CHILDREN,DOCS or ALL).
@param string[] attribute What attributes to
fetch on base parts.
@param string[] part_atts What attributes to
fetch on related parts.
@param string[] partmaster_atts What attributes to fetch on
related part masters.
@param string[] doc_atts What attributes to
fetch on related documents.
@return INFOENGINE_GROUP ${partRelations}
-->

<ie:webject name="Fetch-PartRelations" type="OBJ">
<ie:param name="INSTANCE" data="$(@FORM[]supporting-adapter[*])"
delim="!" valueSeparator="!"
default="<%=com.infoengine.au.NamingService.getVMName()%>"/>
<ie:param name="OBJECT_REF" data="${@FORM[]object_ref[*]}"
valueSeparator="!" delim="!" />
   <ie:param name="TYPE" data="${@FORM[]type[0]}"
default="wt.part.WTPart" />
   <ie:param name="WHERE" data="${@FORM[]where[0]}" />
   <ie:param name="FETCH_WHAT" data="${@FORM[]what[*]}"
default="ALL" delim="," />
   <ie:param name="ATTRIBUTE" data="${@FORM[]attribute[*]}"
default="name,number" delim="," />
   <ie:param name="PART_ATTRIBUTES" data="${@FORM[]part_atts[*]}"
default="name,number,masterReference" delim="," />
   <ie:param name="PARTMASTER_ATTRIBUTES"
data="${@FORM[]partmaster_atts[*]}" default="name,number"
delim="," />
  <ie:param name="DOCUMENT_ATTRIBUTES"
data="${@FORM[]doc_atts[*]}" default="name,number" delim=","
/>
<ie:param name="GROUP_OUT" data="partRelations" />
</ie:webject>
The following starts the server management utility and method server. Then, execute it with a URL as before. For example:
http://host.company.com/Windchill/servlet/IE/tasks/ext/example/
Fetch-PartRelations.xml?where=name='ParentPart'
In this case we are only specifying the where parameter and letting all the other defaults as defined in the task source be used.
The output from the URL would be similar to the following:
<?xml version="1.0" encoding="UTF-8"?>
<wc:COLLECTION xmlns:wc="http://www.ptc.com/infoengine/1.0">
<wt.part.WTPart NAME="partRelations" TYPE="Unknown" STATUS="0">
<wc:INSTANCE>
<obid>VR:wt.part.WTPart:36028:925175337-1180978871749-4365289-
98-8-253-132@host.company.com</obid>
<class>wt.part.WTPart</class>
<name>ParentPart</name>
<number>PARENTPART.0</number>
<parents>
<wc:INSTANCE>
<obid>VR:wt.part.WTPart:36089:925175337-1180978871749-
4365289-98-8-253-132@host.companny.com</obid>
<class>wt.part.WTPart</class>
<masterReference>OR:wt.part.WTPartMaster:36087:925175337-
1180978871749-4365289-98-8-253-
132@padams03l.ptcnet.ptc.com</masterReference>
<number>ROOTPART.0</number>
<name>RootPart</name>
</wc:INSTANCE>
</parents>
<children>
<wc:INSTANCE>
<obid>OR:wt.part.WTPartMaster:36051:925175337-
1180978871749-4365289-98-8-253-132@host.company.com</obid>
<class>wt.part.WTPartMaster</class>
<name>ChildPart</name>
<number>CHILDPART.0</number>
</wc:INSTANCE>
</children>
<children>
<wc:INSTANCE>
<obid>OR:wt.part.WTPartMaster:42041:925175337-1180978871749-
4365289-98-8-253-132@host.company.com</obid>
<class>wt.part.WTPartMaster</class>
<name>AnotherChild</name>
<number>ANOTHERCHILD.0</number>
</wc:INSTANCE>
</children>
<documents>
<wc:INSTANCE>
<obid>VR:wt.doc.WTDocument:32023:925175337-1180978871749-
4365289-98-8-253-132@host.company.com</obid>
<class>wt.doc.WTDocument</class>
<name>wcadapter.txt</name>
<number>WCADAPTER.TXT.0</number>
</wc:INSTANCE>
</documents>
</wc:INSTANCE>
</wt.part.WTPart>
</wc:COLLECTION>
The FETCH_WHAT parameter is an enumerated parameter type. Acceptable values for that parameter are based on the coded enumeration. If a caller were to supply an invalid value for the FETCH_WHAT parameter they would receive a localized error message similar to the following:
<?xml version="1.0" encoding="UTF-8"?>
<wc:COLLECTION xmlns:wc="http://www.ptc.com/infoengine/1.0">
<exception NAME="exception" TYPE="Exception" STATUS="-1">
<wc:MESSAGE>wt.util.WTException: Fetch-PartRelations: Invalid value
&quot;NOTHING&quot; for parameter &quot;FETCH_WHAT&quot;. Must be
one of &quot;[PARENTS, CHILDREN, DOCS, ALL]&quot;.</wc:MESSAGE>
<wc:INSTANCE>
<hierarchy>com.infoengine.util.IEException</hierarchy>
<hierarchy>javax.servlet.jsp.JspException</hierarchy>
<hierarchy>java.lang.Exception</hierarchy>
<hierarchy>java.lang.Throwable</hierarchy>
<hierarchy>java.lang.Object</hierarchy>
</wc:INSTANCE>
</exception>
</wc:COLLECTION>