Extend Windchill ESI Java Code
Background
Windchill ESI services features are implemented using Info*Engine tasks and java classes. Details about these tasks and classes can be found in the Windchill ESI Services Modules section of this document. These services can be extended using the Windchill Information Modeler, which is described in the Windchill Customization Guide (Windchill 自訂指南).
Several key features of the Windchill services can also be quickly customized without using the Windchill Information Modeler. The following customization mechanisms are available:
VDB builder
The Windchill ESI response is an XML document, generated by the toXML API of Info*Engine from the contents of an Info*Engine Virtual Database (VDB). See the Info*Engine User's Guide (Info*Engine 使用指南) for more information about the Info*Engine VDB. Windchill ESI services provide a set of classes that structure the VDB so that the ESI response output XML is formatted correctly. Details about the VDB builder (including those pertaining to its customization) are located in the VDB Builder section of this document.
Multiple renderers
Renderers are objects that process Windchill objects and convert those objects into Info*Engine Element objects that are managed and formatted by the Windchill ESI VDB builder (See the VDB Builder section of this document). Windchill ESI services provide the following renderers:
Renderer Class
Objects Rendered
ESIRenderer
N/A – this is an interface implemented by class
BasicESIRenderer, described below.
BasicESIRenderer
N/A - this serves as an abstract base class for all of the renderer classes listed below.
ESIAlternateUnitOfMeasureRenderer
AlternateUnitOfMeasure (which holds the alternate unit of measure information for an AlternateUnitAssignable object such as a part master, a process plan master etc.)
ESIWTChangeOrder2Renderer
WTChangeOrder2 and all of the changeable objects
ESIECNHeaderRenderer
WTChangeOrder2
ESIBOMRenderer
Windchill product structure
ESIBOMHeaderRenderer
Windchill part/resource that is representative of the given BOM assembly
ESIBOMSubordinateRenderer
N/A – this serves as an abstract base class for classes ESIBOMComponentRenderer, ESISubstituteRenderer and ESIReferenceDesignatorRenderer
ESIBOMComponentRenderer
PartUsageInfo object (which describes a WTPartUsageLink object)
ESISubstituteRenderer
PartUsageInfo object (which describes a WTPartSubstituteLink object)
ESIReferenceDesignatorRenderer
PartUsageInfo object (which describes a UsesOccurrence object)
ESIWTPartRenderer
WTPart and any associated WTPartMaster and WTPartAlternateLink objects EnterpriseData object associated with WTPart object.
ESIAbstractDocumentsRenderer
N/A – this serves as an abstract base class for class ESIEPMDocumentRenderer.
ESIDocumentsRenderer
PartDocInfo object (which describes WTDocument, EPMDocument, WTPartReferenceLink, WTPartDescribeLink, BuildHistory, ERPMaterialDocumentDescribeLink, ERPMaterialDocumentReferenceLink and ERPMaterialEPMDocumentDescribeLink objects)
* 
This class renders WTDocuments and CAD documents that are associated to RevisionControlled objects, and also standalone WTDocuments.
ESIEPMDocumentRenderer
CAD document and its dependents (viz., CAD documents that are associated to the primary document via a member or a reference association).
* 
This class renders CAD document structures and standalone CAD documents.
ESIMadeFromObjectRenderer
A Made From Object such as a Made From Set or a Co-Produce.
ESIPromotionRequestRenderer
PromotionNotice and all the associated Promotable objects. However, only the Promotable objects are sent with the ESI response by default; if the PromotionNotice is to be sent as well, it would call for customizing the ESI response meta information file.
ESIProcessPlanRenderer
MPMProcessPlan and all the associated objects such as sequences, operations, standard procedures, documents, BOMs etc.
ESIProcessPlanHeaderRenderer
The MPMProcessPlan object and its attributes.
ESIStandardProcedureLinkRenderer
MPMStandardProcedureLink (which links a process plan/sequence/operation to its standard procedure).
ESIPartToProcessPlanLinkRenderer
MPMPartToProcessPlanLink (which links a process plan to its part).
ESIWorkInstructionRenderer
N/A – renders work instructions associated with an MPMOperationHolder such as an MPMOperation.
ESISequenceRenderer
MPMSequence and its associated objects such as documents and standard procedures.
ESISequenceUsageLinkRenderer
MPMSequenceUsageLink (which links a process plan to its sequence).
ESIOperationRenderer
MPMOperation and all the associated objects such as sub- operations, standard procedures, BOM allocated parts, operated on parts, work instructions, documents, resources etc.
ESIOperationUsageLinkRenderer
MPMOperationUsageLink (which links a process plan/sequence/operation to its operation/sub-operation).
ESIOperationToPartLinkRenderer
MPMOperationToPartLink (which links an operation to its BOM allocated part).
ESIOperatedOnPartLinkRenderer
MPMOperationToOperatedPartLink (which links an operation to the “operated on” part).
ESIOperationConsumableResourceRenderer
MPMOperationToConsumableLink (which links an operation to a consumable resource, such as a tooling or a process material).
ESIOperationWorkCenterRenderer
MPMOperationToWorkCenterLink (which links an operation to a work center).
ESIResourceRenderer
N/A – this serves as an entry point for the processing of various types of resources (such as tooling, process materials and skills); it instantiates a resource renderer of the appropriate type and delegates the processing of the given resource to that instance.
ESIToolingRenderer
MPMTooling and all the associated resources and documents.
EnterpriseData object associated with MPMTooling object.
ESIProcessMaterialRenderer
MPMProcessMaterial and all the associated resources and documents. EnterpriseData object associated with MPMProcessMaterial object.
ESISkillRenderer
MPMSkill and all the associated resources and documents.
EnterpriseData object associated with MPMSkill object.
ESIPlantStructureRenderer
MPMPlant and all the associated resources and document.
EnterpriseData object associated with MPMPlant object
ESIResourceGroupStructureRenderer
MPMResourceGroup and all the associated resources and document.
EnterpriseData object associated with MPMResourceGroup object.
ESIWorkCenterRenderer
MPMWorkCenter and and all the associated resources and document.
EnterpriseData object associated with MPMWorkCenter object.
ESIControlCharacteristicRenderer
MPMControlCharacteristic and the associated ModelItem.
ESIQualityLinkRenderer
MPMPartQualityLink (which links a part to a control characteristic), MPMProcessQualityLink (which links a process plan to a control characteristic) and MPMOperationQualityLink (which links an operation to a control characteristic master).
ESIResourceUsageLinkRenderer
WTPartUsageLink that is a part of the resource structure and associates MPMResource to MPMResourceMaster or WTPartMaster.
ESIProcessPlanLocalizationLinkRenderer
MPMProcessPlanLocalizationLink that associates MPMProcessPlan to Line type of WorkCenter.
ESIPlantLocalizationLinkRenderer
MPMPlantLocalizationLink that associates WorkCenter to Operation.
The renderers that are listed below in this table are available when ESI Options and Variants is installed. However, for the Winchill 11.0 release, integration of Options & Variants to SAP is not supported.
OptionSetRenderer
OptionSet and associations such as OptionSetMemberLinks, OptionSetChoiceRuleMasterLink/OptionSetChoiceRuleLink and OptionSet to Option virtual link.
AssignedOptionSetLinkRenderer
OptionSet to Part association.
ChoiceRuleRenderer
ChoiceRule renderer
OptionRenderer
Option and Choice object renderer
ExpressionRenderer
Basic and Advance Expression that are Dependent or Independent are rendered by this renderer.
RuleMemberLinkRenderer
ExpressionMemberLink or SourceChoice are rendered by this renderer.
RuleMemberActionLinkRenderer
RuleMemberActionLink or ChoiceMappableChoiceLink renderer.
Windchill ESI Renderers
As mentioned in the above table, each of the renderer classes provided by ESI services extends the abstract class BasicESIRenderer, which in turn implements the interface ESIRenderer. The class BasicESIRenderer provides concrete implementations of a number of methods besides public void render(VdbBuilder), the only method provided by the ESIRenderer interface.
The following table lists the names of classes that provide concrete implementations for the various getXXX() APIs of ESI services:
Java Class Name
API Name
ESIWTChangeOrder2Renderer
getECN
ESIBOMRenderer
getBOM
ESIWTPartRenderer
getPart
ESIDocumentsRenderer
getDocument
ESIEPMDocumentRenderer
getDocument, getEPMDocument
ESIProcessPlanRenderer
getProcessPlan
ESIResourceRenderer
getResource
ESIPromotionRequestRenderer
getPromotionRequest
OptionSetRenderer
getOptionSet
See the Windchill Enterprise Systems Integration Open Application Programming Interface Guide (Windchill Enterprise Systems Integration Open Application 程式撰寫介面指南) and also the sections Publishing CNs, Publishing BOMs, Publishing Parts, Publishing Documents, Publishing Process Plans, Publishing Resources and Publishing Promotion Requests for details about the getXXX() APIs.
Likewise, the classes ESIProcessPlanRenderer and ESIResourceRenderer provide the concrete implementations for the GetProcessPlan and GetResource response generators. See the Windchill Enterprise Systems Integration Open Application Programming Interface Guide (Windchill Enterprise Systems Integration Open Application 程式撰寫介面指南) and the Publishing Process Plans and Publishing Resources sections of this document for details about the GetProcessPlan and GetResource methods.
Creating object specific renderer implementations
Windchill ESI services provide a number of renderer classes that handle GetXXX requests initiated by a user. Each of these classes extends the abstract class BasicESIRenderer, which in turn implements the interface ESIRenderer by providing a concrete implementation for the method public void render(VdbBuilder). This method calls setBuilder(), validate() and buildGroups() – while BasicESIRenderer provides a concrete implementation for setBuilder(), it merely provides abstract versions of validate() and buildGroups(). The corresponding concrete versions are provided by the object specific renderer implementations. For example, class ESIWTPartRenderer implements these methods in ways that are appropriate for the rendering of WTPart objects.
ESI services provide a default renderer implementation for each of the object types mentioned in the Objects Rendered column of the table Windchill ESI Renderers. All of these implementations allow for extensions by customizers.
Obtaining the renderer implementation from a factory
ESI services make use of an ESIRendererFactory instance to fetch the renderer implementation that is appropriate for a given GetXXX request. The class ESIRendererFactory provides overloaded versions of the method getRenderer(), which returns an ESIRenderer instance of an appropriate type, based on input parameters passed to it. The factory class is not intended to be customized, but only to facilitate customization.
Following are the available methods in class ESIRendererFactory:
getRenderer(anObject : Persistable) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object in the argument anObject. It does this by fetching the UFID of the passed object and then invoking getRenderer(ufid : String).
getRenderer(ufid : String) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object, whose UFID is passed in the argument ufid. This method may be used for object types where the <Option> element does not carry a selector attribute in the xconf file that lists ESI service properties.
getRenderer(ufid : String, selector : String) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object whose UFID is passed in the argument ufid and for the given selector. This method may be used for object types where the <Option> element carries a selector attribute in the xconf file that lists ESI service properties.
getRenderer(anObject : Persistable, selector : String) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object in the argument anObject and for the given selector.
getRenderer(requestor : Class, selector : String) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object, whose Class is passed in the argument requestor, and for the passed selector. Some of the overloaded forms described above invoke this method to get their job done. A call to this method will always result in a newly created renderer instance being returned.
getInstance() : ESIRendererFactory
Returns the value in the class variable manager, if it exists. Otherwise, creates a new instance of ESIRendererFactory using a protected argumentless constructor, initializes manager and returns it to the caller.
getRenderer(ufid : String, useCache : boolean) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object, whose UFID is passed in the argument ufid. This method may be used for object types where the <Option> element does not carry a selector attribute in the xconf file that lists ESI service properties. The method either fetches the renderer instance from cache or creates a new instance, according as useCache is true or false respectively.
getRenderer(ufid : String, selector : String, useCache : boolean) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object whose UFID is passed in the argument ufid and for the given selector. This method may be used for object types where the <Option> element carries a selector attribute in the xconf file that lists ESI service properties. The method either fetches the renderer instance from cache or creates a new instance, according as useCache is true or false respectively.
getRenderer(requestor : Class, selector : String, useCache : boolean) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object, whose Class is passed in the argument requestor, and for the passed selector. The method getRenderer(requestor : Class, selector : String) gets its job done by invoking this method, passing in a false for the argument useCache, with the result that a newly created renderer instance is always returned to the caller.
getRenderer(anObject : Persistable, selector : String, useCache : boolean) : ESIRenderer
Fetches an ESIRenderer instance of the required type for the object in the argument anObject and for the given selector. The method either fetches the renderer instance from cache or creates a new instance, according as useCache is true or false respectively.
* 
When invoking a getRenderer() API that takes in the useCache argument, it is recommended that a false be passed for useCache, since passing a true would result in a renderer instance being fetched from cache, which may already be in use by a concurrently executing transaction.
As someone customizing Windchill Enterprise Systems Integration, you may choose to extend the default renderer implementation class or write a new implementation class. The extension (or the new implementation) can be activated by making a certain Windchill ESI service property point to the extension (or the new) class, and by making the responseMetaInfoPath attribute on the relevant ESITarget object point to an appropriately modified version of the ESI response meta information file, containing entries for additional attributes that may be rendered by the extension (or the new) class. See the Modifying Windchill ESI Preference section of this document for information about changing the contents of the response meta information file. See the Windchill ESI Services Customizations of this document for a description of the property to change when extending a default renderer implementation or providing a new renderer implementation class.
Providing a hook
Each of the default renderer implementation classes produces Info*Engine Element objects. These Element objects are passed to the VDB builder. Most default renderers provide a method called adjustElement() - where this method is available, it is always called by the default renderer immediately before passing the element to the builder. The default implementation of the method is to do nothing.
The Windchill ESI mapper facility provides access only to the getter methods of the objects that are mapped. The mapper does not provide complex logic capabilities. The adjustElement()method provides a simple way to add or modify the renderer output in cases where changes to the response meta information file are insufficient to achieve the desired result.
Procedure
Procedures for extending Windchill ESI classes using the Windchill Information Modeler are defined in the Windchill Customization Guide (Windchill 自訂指南). For simple extensions of the default interface implementation use this process:
1. Make any changes to the ESI response meta information file as may be appropriate.
* 
Remember to follow the procedure described in section Modify the ESI Response Meta Information File while performing the above step.
2. Set the responseMetaInfoPath attribute on the relevant ESITarget object(s) to point to the modified version of the file.
* 
The above may be achieved by modifying the value of the ESI Response Meta Information File Path field appearing in the Edit Distribution Target or the New Distribution Target dialogue of the Manage Distribution UI.
3. Define the java source file using the editor or Integrated Development Environment (IDE) of your choice.
* 
Caution: Do not modify or replace any classes that were provided when Windchill ESI was installed. These files may be replaced by future software releases.
4. Compile the java source file into the Windchill codebase.
5. Change the appropriate Windchill ESI service property to point to your new renderer implementation.
6. Modify the XML schema and possibly the EAI software components, if your change causes the addition of any new elements to the output.
Example: Adding an Attribute to <Part> by Extending the Renderer
The default output for the Part XML element is shown in the figure Default Part XML Element Structure. The Map element in the default response meta information file is shown in the Example: Adding an Attribute to <Part> section of this document.
The new <Part> element now has an additional child element, <Team>.
The modified Map and MapInformation elements of the response meta information file will take the form shown below:
<esi:Map id="ESINewPart">
<esi:attributeMapping sourceAttribute="obid">ObjectID</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx" defaultValue="com.ptc.windchill.esi.Part">Class</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="modifier">LastChangedBy</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="number">Number</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">StartEffectivity</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">EndEffectivity</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">StartSerialNumberEffectivity</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">EndSerialNumberEffectivity</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">StartLotNumberEffectivity</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">EndLotNumberEffectivity</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">SerialNumberEffectivityCxtPartNumber</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="xxxx">LotNumberEffectivityCxtPartNumber</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="defaultUnit">DefaultUnit</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="name">Name</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="partType">PartType</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="source">Source</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="state.state">State</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="view" plantSpecificAttribute="true">View</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="storageLocation" plantSpecificAttribute="true">StorageLocation</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="phantom">IsPhantom</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="versionInfo.identifier.versionId">Version</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="iterationInfo.identifier.iterationId">Iteration</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="PreviousVersion">PreviousVersion</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="genericType">IsConfigurable</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="collapsible">IsCollapsible</esi:attributeMapping>
<esi:attributeMapping sourceAttribute="team">Team</esi:attributeMapping>
</esi:Map>

<esi:MapInformation id="ESIPartInfo">
<esi:typedef>wt.part.WTPart</esi:typedef>
<esi:elementMetaName>Part</esi:elementMetaName>
<esi:keyAttribute>Number</esi:keyAttribute>
<esi:keyAttribute>Version</esi:keyAttribute>
<esi:keyAttribute>PreviousVersion</esi:keyAttribute>
<esi:keyAttribute>View</esi:keyAttribute>
<esi:keyAttribute>StorageLocation</esi:keyAttribute>
<esi:mapRef>ESINewPart</esi:mapRef>
</esi:MapInformation>
The response meta information file with the above described changes is located in <:Windchill>:/codebase/com/ptc/windchill/esi/examples/ESIResponseMetaInfoExample2.xml.
The Windchill ESI mapper generates the following output if the file ESIResponseMetaInfoExample2.xml were used:
Customized Part XML Element Structure – Example 2
The mapper may not be able to obtain the required data since a WTPart object does not have an attribute called team. As a result, activating the modified version of the response meta information file results in an empty <Team> element in the ESI response. This could be fixed by either extending WTPart to include the team attribute, or by extending Windchill ESI’s ESIWTPartRenderer class to fill in the empty team value. The class Example2MyRenderer shows how to extend the class ESIWTPartRenderer. The source code for the class is located in <Windchill>/codebase/com/ptc/windchill/esi/examples/Example2MyRenderer.java.
These are the contents of the sample file:
package com.ptc.windchill.esi.examples;

import com.infoengine.object.factory.Att; import com.infoengine.object.factory.Element;
import com.ptc.windchill.esi.esipart.ESIWTPartRenderer;
systematically, systems integrators/customizers can add validation import java.util.Collection;
import wt.eff.Eff; import wt.part.WTPart;


public class Example2MyRenderer extends ESIWTPartRenderer {

// This example method will adjust the mapper to return a value for the attribute "Team". If the attribute "Team" is found
// and the value is null or empty, then this method will update the value.

protected Element adjustPartElement( Element elem,
String group, WTPart part, Eff [] effs,
Collection targets )
throws ESIRendererException {
Att att = elem.getAtt("Team"); // get the attribute "Team" from the mapper output

if ( att != null ) // verify that the attribute exists in the mapper
{
//Check to see if the value of "Team" is null or is empty.
if ( att.getValue() == null || att.getValue().toString().trim().equals(""))
{
// Get the value for "Team" from the part object and use it to set
// the value for the "Team" attribute in the mapper output. att.setValue(part.getTeamName());
}
}

return elem;
}
}
Consider the following:
The package statement ensures that the output of the java compiler is written to the correct directory.
The java import statements are required because of the inheritance of the class and the arguments to the adjustElement() method.
The if statement, if ( att != null ) allows the mapper to control the presence of the team attribute. It does so by attempting to obtain the Att object whose name is "Team" from the mapper output. If there is no attributeMapping entry with the value "Team" in the relevant Map element of the response meta information file, the result of the attempt to obtain the Att object will be null.
The if statement, if ( att.getValue() == null || att.getValue().toString().trim().equals(""))checks to see if the mapper was able to obtain the desired data. If the data was obtained, nothing is done. This is the recommended way to override the behavior of the mapper.
You can compile and run the example by doing the following:
Launch the Windchill shell from within the Windchill directory that was defined when you installed Windchill with this command: bin/windchill shell
Use the java compiler to compile the class javac -d ./codebase ./codebase/com/ptc/windchill/esi/examples/*.java
Use the Manage Distribution UI to bring up the Edit Distribution Target (or the New Distribution Target) dialogue, and edit the value of the ESI Response Meta Information File Path field to point to the file ESIResponseMetaInfoExample2.xml. Click OK to save the changes and have the edited (or the newly created) distribution target associated to the part being released.
* 
Caution: The above described procedure causes Windchill ESI services to use the example response meta information file when rendering parts. This changes the structure of the ESI response for GetPart, GetBOM, GetECN, GetProcessPlan and GetPromotionRequest. Changing the structure causes the XML schemas in Windchill and the EAI software components to become out of synch. If you make a change to the response meta information file, you must modify the XML schema as described in the Create/Modify XML Schema section of this document. You must also modify the EAI software components to use the new schema. See the XML schemas section of this document for details.
The following XML document serves as an input to the xconfmanager command to activate the new part renderer class:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Configuration SYSTEM "xconf.dtd">
<Configuration targetFile="codebase/service.properties">
<!-- The ESIRenderer entries for use by com.windchill.esi.rnd.ESIRendererFactory -->
<Service context="default" name="com.ptc.windchill.esi.rnd.ESIRenderer">
<Option cardinality="duplicate" requestor="wt.part.WTPart" serviceClass="com.ptc.windchill.esi.examples.Example2MyRenderer"/>
</Service>
</Configuration>
The file is located in <Windchill>/codebase/com/ptc/windchill/esi/examples/Example2.service.properties.xconf.
The following command propagates the changes specified in the file to the file <Windchill>/codebase/service.properties:
xconfmanager –i codebase/com/ptc/windchill/esi/examples/Example2.service.properties.xconf –p
The XML schema definition for the Windchill ESI response that is generated when the customized response meta information file is used is located in <Windchill>/codebase/com/ptc/windchill/esi/examples/Example2.xsd.
The Windchill ESI response that is generated when the customized response meta information file is used is located in <Windchill>/codebase/com/ptc/windchill/esi/examples/Example2.xml.
* 
Besides extending the VDB builder and any of the ESI renderers, it is possible to extend the ESI response generator and ESI service implementations. See the ESIResponseGenerator and StandardESIService sections for more information.
這是否有幫助?