Professional Documents
Culture Documents
WindchillCustomizationGuide 12 0 2 0 PDF
WindchillCustomizationGuide 12 0 2 0 PDF
12.0.2.0
Copyright © 2022 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
User and training guides and related documentation from PTC Inc. and its subsidiary companies (collectively
"PTC") are subject to the copyright laws of the United States and other countries and are provided under a
license agreement that restricts copying, disclosure, and use of such documentation. PTC hereby grants to the
licensed software user the right to make copies in printed form of this documentation if provided on software
media, but only for internal/personal use and in accordance with the license agreement under which the
applicable software is licensed. Any copy made shall include the PTC copyright notice and any other
proprietary notice provided by PTC. Training materials may not be copied without the express written consent
of PTC. This documentation may not be disclosed, transferred, modified, or reduced to any form, including
electronic media, or transmitted or made publicly available by any means without the prior written consent of
PTC and no authorization is granted to make copies for such purposes. Information described herein is
furnished for general information only, is subject to change without notice, and should not be construed as a
warranty or commitment by PTC. PTC assumes no responsibility or liability for any errors or inaccuracies
that may appear in this document.
The software described in this document is provided under written license agreement, contains valuable trade
secrets and proprietary information, and is protected by the copyright laws of the United States and other
countries. It may not be copied or distributed in any form or medium, disclosed to third parties, or used in any
manner not provided for in the software licenses agreement except with written prior approval from PTC.
PTC regards software piracy as the crime it is, and we view offenders accordingly. We do not tolerate the
piracy of PTC software products, and we pursue (both civilly and criminally) those who do so using all legal
means available, including public and private surveillance resources. As part of these efforts, PTC uses data
monitoring and scouring technologies to obtain and transmit data on users of illegal copies of our software.
This data collection is not performed on users of legally licensed software from PTC and its authorized
distributors. If you are using an illegal copy of our software and do not consent to the collection and
transmission of such data (including to the United States), cease using the illegal version, and contact PTC to
obtain a legally licensed copy.
Important Copyright, Trademark, Patent, and Licensing Information: See the About Box, or copyright
notice, of your PTC software.
PTC software products and software documentation are “commercial items” as that term is defined at 48 C.F.
R. 2.101. Pursuant to Federal Acquisition Regulation (FAR) 12.212 (a)-(b) (Computer Software) (MAY 2014)
for civilian agencies or the Defense Federal Acquisition Regulation Supplement (DFARS) at 227.7202-1(a)
(Policy) and 227.7202-3 (a) (Rights in commercial computer software or commercial computer software
documentation) (FEB 2014) for the Department of Defense, PTC software products and software
documentation are provided to the U.S. Government under the PTC commercial license agreement. Use,
duplication or disclosure by the U.S. Government is subject solely to the terms and conditions set forth in the
applicable PTC software license agreement.
3
Allocate Database Columns for Local Attributes ........................................... 188
Create a New Attribute Definition and Add it to the Document Type................ 191
As the End User, Create a Document with the new Attribute .......................... 198
Create a Document Subtype ....................................................................... 201
Create an Instance of the New Document Subtype ....................................... 205
Model a New Document Subclass ............................................................... 206
Create an Instance of the New Document Subclass...................................... 213
Verify the Customizations ........................................................................... 216
Customization Tutorial Summary................................................................. 217
Example: Create a modeled Object with Derived Attributes from modeled
Master Class .......................................................................................... 217
User Interface Customization............................................................................. 219
User Interface Technology Overview .................................................................. 222
Windchill Client Architecture Overview......................................................... 223
Windchill Client Architecture Common Objects Overview .............................. 236
Javascript Functions Overview.................................................................... 238
Adding Custom Code to all Windchill Client Architecture Pages ..................... 245
MVC Components ............................................................................................ 247
MVC Components Overview ....................................................................... 248
MVC Tables ............................................................................................... 275
Customizing HTML Clients Using the Windchill JSP Framework........................... 276
Customizing Generic Aspects of JSP Pages ................................................ 277
Bread Crumbs Component ......................................................................... 285
Client Tabs ................................................................................................ 298
Customization Points.................................................................................. 302
Exporting and Importing Client Tabs ............................................................ 310
Sample Code............................................................................................. 312
Checkin/Checkout...................................................................................... 312
Component Access Control ........................................................................ 316
Attachments .............................................................................................. 322
Attribute Panels ......................................................................................... 333
Customizing Access Control For Packages .................................................. 378
Customization Tools Overview .................................................................... 381
Adding Validation Logic for Actions and Properties ....................................... 414
Split Pane / Two Pane ................................................................................ 429
Defining Layouts in a Type Load File ........................................................... 439
Configuring the Drag and Drop Zone ........................................................... 443
Generic UI Customizations ................................................................................ 446
Customizing Role-Based UI Functions - Attribute Visibility............................. 447
Customizing Role-Based UI Functions — Action Visibility.............................. 458
Preference Framework ............................................................................... 459
Constructing URLs ..................................................................................... 465
Offline Package Customization ................................................................... 465
System Banner Alert Message .................................................................... 468
Adding a Status Glyph ................................................................................ 469
4 Customization Guide
Adding Actions and Hooking Them Up in the UI .................................................. 473
Action Framework for Windchill Client Architecture ....................................... 474
Tab Models................................................................................................ 499
Customizing Role-based Visibility................................................................ 509
User Interface Stickiness ............................................................................ 522
Defining Menus.......................................................................................... 523
Adding Custom Content to the Home Page .................................................. 539
Gathering the Data for the UI ............................................................................. 543
Acquiring Data via Info*Engine.................................................................... 544
NmObject Utilities ...................................................................................... 550
File Download............................................................................................ 556
Presenting Information in the UI ......................................................................... 562
Dynamically Resolved Attributes for Customizations..................................... 563
Constructing and Rendering a Table Using the JSP Framework..................... 564
Windchill Client Architecture Tree ................................................................ 599
Attribute Customization .............................................................................. 615
Adding Custom Modeled Attributes to all Table Views ................................... 688
Attribute Tables.......................................................................................... 689
Icon Delegates........................................................................................... 693
Creating Custom Graphical Representations................................................ 700
UI Validation .............................................................................................. 723
URL Authorization...................................................................................... 773
Customizing the Find Number Field ............................................................. 777
Inline Messaging........................................................................................ 784
Linking to Help Topics................................................................................. 788
Constructing Wizards........................................................................................ 790
Windchill Client Architecture Wizard ............................................................ 791
Wizard Processing ..................................................................................... 819
Building Wizards to Create a Single Object .................................................. 844
Building Wizards to Edit a Single Object....................................................... 866
Customizing Reusable Wizard Steps ........................................................... 879
Handling External Requests Using an MVC Controller .................................. 919
Client Generated Form Data ....................................................................... 923
Information Pages ............................................................................................ 930
Customizing Information Page Components................................................. 931
Solution..................................................................................................... 933
Customization Points.................................................................................. 938
Sample Code............................................................................................. 954
Updating Legacy information Pages ............................................................ 957
Incorporating Pickers in JSP Clients................................................................... 961
Configuring Pickers .................................................................................... 962
Configuring a Context Picker....................................................................... 972
Configuring an Item Picker.......................................................................... 982
Configuring an Organization Picker ............................................................. 990
Configuring a Type Picker ........................................................................... 999
Contents 5
Configuring a User Picker ......................................................................... 1017
Configuring a Participant Picker in JCA...................................................... 1024
Configuring a Participant Picker in AngularJS............................................. 1036
Configurable Links .......................................................................................... 1043
Configurable Link Tables .......................................................................... 1044
Collecting Configurable Links.................................................................... 1058
Configurable Revision Links...................................................................... 1070
Windchill Search Customization....................................................................... 1073
Customizing Indexing Behavior ................................................................. 1074
Customizing Solr...................................................................................... 1076
Customizing Faceted Search .................................................................... 1081
Enabling Text Preview Column for Additional Objects ................................. 1083
Business Logic Customization ......................................................................... 1084
Encrypted Passwords ..................................................................................... 1088
Encrypted Passwords............................................................................... 1089
Solution................................................................................................... 1090
Procedure – Encrypting Static .xconf Managed Single-Valued
Properties ............................................................................................ 1094
Customization Points................................................................................ 1099
Customizing the Login Page ............................................................................ 1106
Login Page Customization ........................................................................ 1107
Customizing Business Logic ............................................................................ 1108
Customizing Logic for Structure Compare ...................................................1110
Context Builder Customization Example .....................................................1113
Customizing Change Management ...................................................................1119
Association Constraints ............................................................................ 1120
Addition of Attributes on Links in Change Relationship Table ....................... 1123
Mass Change Operations ......................................................................... 1158
Mass Change Supported Types ................................................................ 1166
Sponsored Problem Reports and Variances ............................................... 1170
Change Management Cardinality .............................................................. 1173
Change Management Delegate................................................................. 1177
Change Management Transitions.............................................................. 1179
Change Template Initialization Rules ........................................................ 1184
Replicated Objects as Change Task Resulting Objects ............................... 1187
Evaluating Business Rules On Demand..................................................... 1193
Change Workflow Closure ........................................................................ 1202
Flexible Change Links for Query Builder .................................................... 1210
Business Rules............................................................................................... 1220
Customizing Business Rules..................................................................... 1221
Business Rules Configuration and Execution ............................................. 1224
Bypassing Business Rules........................................................................ 1241
Loading Business Rule Objects................................................................. 1249
Business Rule Types................................................................................ 1257
6 Customization Guide
Customizing Workflow Administration............................................................... 1269
Customizing Change Management Workflow Process Templates ................ 1270
Customizing Promotion Request Workflow Processes ................................ 1276
Enhanced Promotion Process................................................................... 1279
Customizing Workflow Events on an Object ............................................... 1291
Customizing Workflow Task Pages ............................................................ 1294
Refine and Review Workflow Transitions ................................................... 1313
Adding Custom Workflow Attribute to Workflow Processes.......................... 1320
Workflow Email Notifications ..................................................................... 1324
Multiple Participant Selection Wizard Customization ................................... 1330
Customizing Change Activity Workflow Assignments .................................. 1340
Customizing Change Tables Designed for Workflow ................................... 1351
Locking Annotations In Change Workflows ................................................ 1357
Customizing Life Cycle Administration.............................................................. 1360
Customizing the Display of Life Cycle Information....................................... 1361
Defining Custom Life Cycle Transitions...................................................... 1363
Setting Up a Customized State-Based Versioning Scheme ......................... 1366
Customizations in Type and Attribute Management ........................................... 1374
Using a BusinessAlgorithm in a Calculated Attribute ................................... 1375
Options and Variants....................................................................................... 1382
Customizing Options and Variants ............................................................. 1383
Configuring Auto-Suggest Results for Options and Choices ........................ 1387
Product Family Management Customizations ................................................... 1393
Custom Actions in Variant Specification Structure....................................... 1394
Custom Actions in Matrix Editor................................................................. 1394
Customizing Product Family Matrix Editor .................................................. 1395
Customizing Matrix Editor Cells................................................................. 1397
Handling Initial Modeled or Soft Attribute Values for New Variant
Specifications ....................................................................................... 1401
Customizing Location in Occurrences Tab.................................................. 1407
Refreshing Selected UI Components from Custom JCA Actions .................. 1422
Customizing Variant Baseline Members ..................................................... 1425
Creating GWT Custom Renderers and Editors ........................................... 1432
Customizing Security Labels............................................................................ 1437
Customizing Security Labels ..................................................................... 1438
Setting Up Custom Security Labels ........................................................... 1440
Specifying Authorized Participants for Custom Security Labels.................... 1452
Additional Considerations for Custom Security Labels ................................ 1455
Customizing Windchill Visualization Services.................................................... 1456
Custom Publishing ................................................................................... 1457
Customizing Publishing Queues................................................................ 1474
Interference Detection .............................................................................. 1481
Modifying the Default Behavior of Dynamic Part Generation ........................ 1489
Report Generation .......................................................................................... 1492
Contents 7
Report Generation Overview..................................................................... 1494
Basic Report Example .............................................................................. 1494
Import and Export of Report Templates ...................................................... 1495
Java Methods .......................................................................................... 1498
Customization Details............................................................................... 1499
Cognos Presentation Customization.......................................................... 1518
Reporting Info*Engine Task Data Source Customization ............................. 1524
Report Loading ........................................................................................ 1530
ReportTemplate Data Source Customization .............................................. 1535
Reporting Input Page Customization ......................................................... 1539
Report Localization Customization ............................................................ 1542
Report Selection List Customization .......................................................... 1548
Jasper Report Customization in Windchill ......................................................... 1559
Jasper Report Authoring Workflow ............................................................ 1561
Authoring Jasper ReportTemplate ............................................................. 1562
Authoring Jasper Report Using ReportTemplate ......................................... 1563
Authoring Jasper Report Using Report Task ............................................... 1579
Authoring Jasper Report Using Windchill REST Services End Points (GET
Method) ............................................................................................... 1583
Execution of the Jasper Reports................................................................ 1585
Saved Report and Scheduling Support for Jasper Reports .......................... 1588
Support for Creating Charts for Jasper Reports .......................................... 1591
Troubleshooting and Reference Information............................................... 1598
Packages Customization................................................................................. 1599
Package Type-Based Properties ............................................................... 1600
Identifying Users in Context Replication and Activating Replicated
Users................................................................................................... 1614
Select Files – Copy Forward Exclusion Decisions ....................................... 1628
Windchill Replication Package Command Line Sample Scripts.................... 1631
Windchill Replication — Out Of Context Collection & Missing
Objects ................................................................................................ 1633
Restrict the Collection of Missing Objects For Defined Contexts and
Recipients ............................................................................................ 1646
Customizing the Collection Logic of Missing Objects................................... 1649
Customization for Downgrading Deliveries ................................................. 1651
Customizing Queue Assignment ............................................................... 1677
DTI Customization Framework......................................................................... 1678
Add Custom Attributes to Microsoft Office .................................................. 1679
Customize the Windchill tab in Microsoft Office........................................... 1680
Customize Windchill Actions in Windows Explorer ...................................... 1696
Customize the DTI Document Search Window ........................................... 1699
Using DTI with Form-Based Authentication ................................................ 1700
Windchill ProjectLink Customization................................................................. 1701
Writing Custom Windchill ProjectLink Algorithms ........................................ 1702
Writing Custom Plan Attributes Algorithms for Members of the Variant
Baseline............................................................................................... 1711
8 Customization Guide
Configuring Automatic Deadline Calculation............................................... 1728
Configuring Automatic Status Calculation .................................................. 1735
Customizing Action Item Attributes ............................................................ 1742
Customizations for PDM.................................................................................. 1746
Customizing the HTML Client Object Selection Page ................................. 1747
Customizing Auto Associate ..................................................................... 1763
Enabling Support for Custom Parts............................................................ 1770
Customizing the Parameters in the Download Service ................................ 1775
Reservation Service........................................................................................ 1777
Reservation Service APIs ......................................................................... 1781
Using the Reservation Service .................................................................. 1781
Using the Reservation Client Tools ............................................................ 1783
Adding the Undo Reservation Action to a Menu .......................................... 1785
Data Exchange using Standards in Windchill .................................................... 1788
STEP Data Exchange using EXPRESS ..................................................... 1790
STEP and PLM Export Import ................................................................... 1979
Windchill Workgroup Manager Customization ................................................... 1984
Custom Windchill Workgroup Manager Requests ....................................... 1986
Creating the Windchill Server-side Customization....................................... 1993
Registering a Custom Service ................................................................... 1997
Pre Operation Customization Hooks for PDM Actions ................................. 1997
CAD Document Structure Publishing to Other Systems ..................................... 2000
CAD Document Structure Publishing to Other Systems............................... 2001
ThingWorx ..................................................................................................... 2003
Adding a ThingWorx Mashup to Windchill .................................................. 2004
Deploying Arbortext Customizations................................................................. 2015
Anonymous Arbortext Access ................................................................... 2016
Customizing Effectivities ................................................................................. 2028
Customizing Effectivity Range Separator ................................................... 2029
Customizing Configuration Specifications and Filters......................................... 2030
Creating Custom Configuration Specifications............................................ 2031
Creating a Custom Configuration Specification Type in Edit Filter UI ............ 2070
Customizing Logic to Determine the Default Configuration
Specifications ....................................................................................... 2071
Creating a Custom Filter ........................................................................... 2072
Creating a Custom Navigation Criteria Filter............................................... 2080
Contents 9
Configuration to display default value set for MPMtooling category attribute
in Windchill........................................................................................... 2099
Custom Data Utility for Identifying Supplier Parts in BOM
Transformer ......................................................................................... 2100
Customizing Report Template to Search for Part ........................................ 2101
Customizing MPMLink Advanced Lifecycle Management with Object
Initialization Rules................................................................................. 2103
Configuring Discrepancy Types and Supporting Interfaces .......................... 2105
Configuring and Customizing Automatic BOM Transformation ..................... 2113
Customizing Flexible Assembly Discrepancy Search .................................. 2123
Customizing Change Number Criteria........................................................ 2125
Customizing Part Attributes and Usage Attributes Criteria ........................... 2126
Customizing Consumption Discrepancy Search ......................................... 2126
Customizing the Comparison Mechanism .................................................. 2127
Propagating Changes Using a Workflow Event........................................... 2128
Comparing Current Revision of a Smart Collection with a Previous
Revision............................................................................................... 2130
Configuring Custom Tabs in BOM Transformer........................................... 2130
Configuring Equivalence Network Delegate ............................................... 2133
Configuring Export Report Delegates......................................................... 2136
Customizing Change Object Search .......................................................... 2140
Configuring Search Delegate for Object Reference Attributes...................... 2142
Configuring Save Delegate for Object Reference Attributes......................... 2145
Customizing MPMLink Browsers ............................................................... 2147
Services and Infrastructure Customization........................................................ 2168
System Generation ......................................................................................... 2170
Modeling Business Objects....................................................................... 2171
Creating New Tablespaces ....................................................................... 2201
Enumerated Types.......................................................................................... 2203
The EnumeratedType Class...................................................................... 2204
Creating an EnumeratedType Subclass ..................................................... 2206
Editing the Resource Info for an Enumerated Type ..................................... 2207
Localizing an Enumerated Type ................................................................ 2209
Extending an Enumerated Type ................................................................ 2210
The Enumerated Type Customization Utility ............................................... 2211
GUI Usage of an Enumerated Type ........................................................... 2213
External Enumerated Value Lists............................................................... 2214
Customizing LDAP Attributes ........................................................................... 2222
Customizing LDAP Mapped Attributes in a User Information Page ............... 2223
Customizing LDAP Mapped Attributes in a Group Information Page............. 2226
System Configuration Collector Plugin.............................................................. 2229
Creating a System Configuration Collector Plugin....................................... 2230
Customizing Modeled Elements....................................................................... 2280
Customizing Column Lengths ................................................................... 2281
10 Customization Guide
Creating Non-Modeled Services for Listening ................................................... 2284
Create a Service Interface ........................................................................ 2285
Create a Standard Service Class............................................................... 2285
Compile................................................................................................... 2288
Register the New Service ......................................................................... 2288
Restart the Method Server ........................................................................ 2289
Contents 11
Creating Large Objects (LOBs) ........................................................................ 2462
Modeling Large Objects............................................................................ 2463
Customizing Data Formats .............................................................................. 2468
Adding and Updating Data Formats for Content Holders ............................. 2469
Customizing Virus Scanner for Content Upload................................................. 2472
Content Virus Scanner ............................................................................. 2473
Java Interface Details ............................................................................... 2474
Configuration and Deployment .................................................................. 2475
Implementation Guidelines ....................................................................... 2475
12 Customization Guide
About This Guide
The Windchill Customization Guide describes how to customize the out-of-the-
box implementation of Windchill. It is intended for developers who are familiar
with Windchill Javadoc.
This guide can be used with all Windchill solutions.
Examples in this guide referencing third-party products are intended for
demonstration purposes only. For additional information about third-party
products, contact individual product vendors.
Note
Some code examples in this guide have been reformatted for presentation
purposes and, therefore, may contain line number, hidden editing characters
(such as tabs and end-of-line characters) and extraneous spaces. If you cut and
paste code from this manual, check for these characters and remove them
before attempting to use the example in your application.
Related Documentation
This guide contains a subset of the customization reference topics from the Basic
Customization, Info*Engine Implementation, and Advanced Customization sections
of the Windchill Help Center. Additional customization information is available in
the following documentation:
• The sections Customizing the Manufacturing Product Structure Explorer and
Customizing MPMLink Browsers in the Windchill Help Center
• Windchill Enterprise Systems Integration Customizer's Guide - Oracle
Applications
• Windchill Enterprise Systems Integration Customizer's Guide - SAP
• The section Info*Engine User’s Guide in the Windchill Help Center
• The section Windchill Adapter in the Windchill Help Center
• The section Info*Engine Java Adapter Development in the Windchill Help
Center
Technical Support
The PTC eSupport portal provides the resources and tools to support your
Windchill implementation:
13
https://www.ptc.com/en/support/
If you encounter problems using this product, contact PTC Technical Support. For
complete details, see “Opening a Case” on the Processes tab of the PTC
Customer Support Guide:
https://www.ptc.com/en/support/csguide
You must have a Service Contract Number (SCN) before you can receive
technical support. If you do not know your SCN, see “Preparing to contact TS” on
the Processes tab of the PTC Customer Support Guide for information about how
to locate it.
Comments
PTC welcomes your suggestions and comments on its documentation:
• To send feedback about a topic you are viewing in the Windchill Help Center,
click the send feedback icon in the top right corner of the topic. The title
of the help topic you were viewing when you clicked the icon is automatically
included with your feedback.
14
• You can also send an email to documentation@ptc.com. To help us more
quickly address your concern, include the name of the PTC product and its
release number with your comments. If your comments are about a specific
help topic or book, include the title.
15
16
Customization Documentation Change
Record
This table details the updates to the Windchill Customization Guide.
Planned Updates
The Windchill Customization Guide in updated on a periodic basis between
Windchill maintenance releases. Check the Reference Documents site on PTC.
com for updates.
17
Release 12.0 Changes
Business Logic Customization
Chapter Changes / Release
Customization Procedure on page 1146 Updated details about adding an entry
for registering a custom table view and
propagating the created xconf files in
Custom Table Views (Step 1) and
Create a Data Utility (Step 3) for the
customization procedure in 12.0.2.0.
Define Mapping Rules for Change Added details about the types of
Management on page 1128 mapping rules and creating the
mapping rules in 12.0.2.0.
Setting Change Intent on page 1127 Added details about setting the change
intent in 12.0.2.0.
Defining Attributes Constraints on page Added details about the Constraints tab
1126 in 12.0.2.0.
Configuring Attributes on Change Added details about adding attributes to
Management Links on page 1123 the change management links in
12.0.2.0.
Addition of Attributes on Links in Created a separate section to
Change Relationship Table on page reorganize, update the existing topics,
1123 and add new topics in 12.0.2.0.
Customizing the History of Added details about a new custom
ModuleVariantInformationLink Using a delegate that provides a mechanism for
Custom Delegate on page 1057 recording history on the
moduleVariantInformationLink in
12.0.1.0.
Business Rules on page 1221 Updated the BOM Release Rule on
page 1266 configuration example.
Customizing Effectivity Range Added details about customizing an
Separator on page 2029 effectivity range separator to use it in
lot number in 12.0.1.0.
Jasper Report Customization on page Added details about Jasper report
1559 customization in 12.0.1.0
Jasper Report Authoring Workflow on Added details about Jasper report
page 1561 customization and the workflow in
12.0.1.0
Authoring Jasper ReportTemplate on Added details about Jasper report
page 1562 customization for jasper report template
in 12.0.1.0
Authoring Jasper Design (JRXML) Added details about Jasper report
Using Report Template on page 1563 customization for authoring Jasper
18
Chapter Changes / Release
design using report template in 12.0.1.0
Authoring Jasper Design (JRXML) Added details about Jasper report
Using Report Tasks on page 1579 customization for authoring Jasper
design using report task in 12.0.1.0
Execution of the Jasper Reports on Added details about Jasper report
page 1585 customization for report execution in
12.0.1.0
Saved Report and Scheduling Support Added details about Jasper report
for Jasper Reports on page 1588 customization for Saved Report in
12.0.1.0
Trobleshooting and References on page Added details about Jasper report
1598 customization and troubleshooting in
12.0.1.0
Customizing Queue Assignment on Added details about customizing the
page 1677 default mechanism for assigning queues
to process full and incremental
replication packages in 12.0.0.0.
19
Release 11.2 Changes
Business Logic Customization
Chapter Changes / Release
Product Structure Explorer Removed these sections related to
Customization: Product Structure Explorer (PSE)
• Customizing PSE Menus, Toolbars customization in 11.2.0.0 release.
and Popup Menus
• Customizing PSE Table Display
• Customizing PSE for Subtypes
• Customizing PSE to Handle
Modeled Subclasses
• Customizing PSE Structure Queries
• Customizing Attribute Displays
within Section Headings
• Customizing Tabs - Configure
Existing Tabs with Subtabs
• Allow Additional Steps During
New Object Creation
• Type Picker Display Customization
• Disabling Actions by Object Type
• Creating a Requirements Tab
• Customizing Configurable Links in
PSE and MPSE
Creating a Custom Configuration Added details about creating custom
Specification Type in Edit Filter UI on configuration specification type in the
page 2070 Edit Filter window in 11.2.0.0.
Customizing Part Structure Browser on Introduced this section in 11.2.0.0 to
page 2088 contain customization chapters in
Product Structure Browser.
Customizing Part Structure Browser New section added in 11.2.0.0 that
Actions Toolbar on page 2089 provides details about adding custom
actions, or tasks, to the Actions toolbar
in the Product Structure Browser.
Displaying Custom Tables in PSB on New section added in 11.2.0.0 that
page 2093 provides details about displaying
custom tables in the Attributes tab in
Product Structure Browser.
Creating a Custom Navigation Criteria New section added in 11.2.0.0 that
Filter on page 2080 provides details about adding a custom
filter tab in the Edit Filter window.
20
Chapter Changes / Release
Creating Custom Configuration New section added in 11.2.1.0 that
Specifications on page 2031 provides details about creating custom
configuration specifications.
Using MultiValued Attributes in New section added in 11.2.1.0 that
Customizing Configuration provides details about using
Specifications on page 2062 multivalued attributes while
customizing configuration
specifications.
Creating Object Reference Picker in New section added in 11.2.1.0 that
Custom Configuration Specification on provides an example on how to create
page 2066 Object Reference picker in your
Configuration Specification
Customization.
Creating a Custom Filter on page 2072 New section added in 11.2.1.0 that
provides details about creating a
custom filter.
Customizing Part Structure Browser Updated the "RibbonInfo Attributes"
Actions Toolbar on page 2089 sub-section with the new entry for
SearchWidget in 11.2.1.0.
Adding a Custom Auto-Suggest Search New section added in 11.2.1.0 that
Widget Component on page 2092 provides details about adding a custom
auto-suggest search widget component.
21
Chapter Changes / Release
Propagating Changes Using a Added details about syncing the
Workflow Event on page 2128 upstream structure with the downstream
structure using a workflow event in
11.2.0.0.
Configuring Custom Tabs in MAPSB Added details about creating custom
on page 2130 tabs in MAPSB in 11.2.1.0.
Configuring Equivalence Network Added details about configuring the
Delegate on page 2133 equivalence network delegate to display
custom output in 11.2.1.0.
Configuring Export Report Delegates Added details about configuring the
on page 2136 delegates for the export associative
report feature to display custom output
in 11.2.1.0.
Customizing Change Object Search on Added details about configuring the
page 2140 search action to display custom results
when searching for change objects in
11.2.1.0.
Configuring Search Delegate for Object Added details about configuring the
Reference Attributes on page 2142 search delegate in object reference
attributes to display custom results in
11.2.1.0.
Configuring Save Delegate for Object Added details about configuring the
Reference Attributes on page 2145 save delegate for object reference
attributes to execute custom actions in
11.2.1.0.
Configuration to display default value Added details about the procedure to
set for MPMtooling category attribute display default value set for
in Windchill on page 2099 MPMtooling category attribute in
11.2.0.0.
Windchill Development Best Practice Added details about displaying related
Name: Show related Accountability Accountability Maps on the part
Maps on Part info page on page 2150 information page in 11.2.1.0.
Custom Data Utility for Identifying Added details about implementing a
Supplier Parts in Manufacturing custom data utility to identify supplier
Associative Part Structure Browser on parts as per business needs in 11.2.1.0.
page 2100
22
Packages Customization
Chapter Changes / Release
Restrict the Collection of Missing New section added in 11.2.1.0 that
Objects For Defined Contexts and provides details about how to restrict
Recipients on page 1646 collection of missing objects for
defined contexts and recipients.
Windchill Replication — Out Of Added the information about the
Context Collection & Missing Objects supported associations for missing
on page 1633 objects in 11.2.1.0.
23
Business Logic Customization
Chapter Changes / Release
Section
Data Exchange Using Standards in New objects were added to AP242
Windchill on page 1788 XPX Mapping Guide on page in 11.1
M010.
New objects were added to AP242
XPX Mapping Guide on page in 11.1
M010.
Customization for Downgrading Added details about transformation
Deliveries on page 1651 filters, dependency filtering for
downgraded deliveries, XSL
transformation scenario and downgrade
repository customization in 11.1.M010.
Transformation Filter on page 1659 Added details about the
contentInclusionCriteria in
the section “Java based Filter” in 11.1.
M020.
Windchill Replication — Out Of Added details about the context
Context Collection & Missing Objects replication properties for out of context
on page 1633 and missing objects in 11.1.M020.
Customizing Life Cycle Administration Updated the screenshots for Life Cycle
on page 1360 Template Administration utility that is
rendered in HTML.
Customizing Workflow Administration Updated the screenshots for Workflow
on page 1269 Template Administration utility that is
rendered in HTML.
Customizing Workflow Events on an Updated the procedure to customize the
Object on page 1291 default resource files for a workflow
event using a Java file.
ProjectLink Customization on page Added details about Writing Custom
1701 Plan Attributes for Members of the
Variant Baseline in 11.1 F000
PLM Export Import on page 1979 Added details about the import and
export for PLM services.
24
Release 11.0 Changes
Windchill Customization Basics
Chapter Changes / Release
Managing Customizations on page 109 • “Modeled to Subtype Conversion”
was updated in 11.0 F000 and
removed in 11.0 M030..
• Monitoring a Customized Windchill
Environment on page 140 was
updated in 11.0 M020.
• Removed the “Modeled to Soft
Type Conversion” section in 11.0
M030.
25
Chapter Changes / Release
Presenting Information in the UI on • Attribute Customization on page
page 562 615 was updated in 11.0 F000 and
11.0 M010..
• Dynamically Resolved Attributes
for Customizations on page 563
was updated in 11.0 F000.
• URL Authorization on page 773
was added in 11.0 M010.
• Creating Custom Graphical
Representations on page 700was
added in 11.0 M020.
Constructing Wizards on page 790 • Customizing Reusable Wizard
Steps on page 879 was updated in
11.0 F000.
• Configuring a Type Picker on page
999 was updated in 11.0 M010.
Incorporating Pickers in JSP Clients on • Configuring a Participant Picker in
page 961 JCA on page 1024 was updated in
11.0 F000.
• Configuring a Participant Picker in
AngularJS on page 1036 was added
in 11.0 F000.
Configurable Links on page 1043 • Configurable Link Tables on page
1044 was updated in 11.0 F000.
26
Chapter Changes / Release
Customizing Online Help • Removed the “Uninstalling the
Windchill LearningConnector”
section in 11.0 M010.
• “Customizing Windchill Help
Center Content” was updated in
11.0 M020.
• The entire “Customizing Online
Help” chapter was removed in 11.0
M030. The help center architecture
changed and those customizations
are no longer supported.
Windchill Search Customization on • Customizing Indexing Behavior on
page 1073 page 1074 was updated in 11.0
F000.
• Customizing Faceted Search on
page 1081 was added in 11.0 M010.
• The “Developing a Custom Search
Application” section was removed
in 11.0 M010.
27
Chapter Changes / Release
Customizing Workflow Administration • Multiple Participant Selection
on page 1269 Wizard Customization
on page 1330 was updated in 11.0
F000.
• Locking Annotations In Change
Workflows
on page 1357 was added in 11.0
F000.
Customizing Life Cycle Administration • Defining Custom Life Cycle
on page 1360 Transitions on page 1363 was
updated in 11.0 M010.
Customizations in Type and Attribute • Using a BusinessAlgorithm in a
Management on page 1374 Calculated Attribute
on page 1375 was added in 11.0
F000.
Customizing Windchill Visualization • Interference Detection on page
Services on page 1456 1481 was updated in 11.0 F000.
• Modifying the Default Behavior of
Dynamic Part Generation
on page 1489
Report Generation on page 1492 • Java Methods on page 1498 was
updated in 11.0 F000.
Packages Customization on page 1599 • Package Type-Based Properties
on page 1600 was updated in 11.0
M020.
DTI Customization Framework on page • Customize the DTI Document
1678 Search Window on page 1699 was
updated in 11.0 F000 and again in
11.0 M020.
• Using DTI with Form-Based
Authentication on page 1700 was
updated in 11.0 M020.
Windchill ProjectLink Customization • Writing Custom Windchill
on page 1701 was added in 11.0 M030. ProjectLink Algorithms on page
1702 was added in 11.0 M030.
• Configuring Automatic Deadline
Calculation on page 1728 was
added in 11.0 M030.
• Configuring Automatic Status
Calculation on page 1735 was
added in 11.0 M030.
28
Chapter Changes / Release
• Customizing Action Item Attributes
on page 1742 was added in 11.0
F000 and in 11.0 M030..
Data Exchange using Standards in • STEP Data Exchange using
Windchill EXPRESS
on page 1788 on page 1790 was updated in 11.0
F000.
• STEP Foundation
on page 1791 was updated in 11.0
M010 to add Configuring Metadata
Mapping on page 1846.
• AP242 XPX Mapping Guide on
page 1889 was added in 11.0 M010.
ThingWorx • Adding a ThingWorx Mashup to
on page 2003 Windchill
on page 2004 was added in 11.0
M020.
29
Changes in Release 10.1 M010 through Release 10.2
M030
The following updates were made in the Windchill customization documentation
in the 10.1 M010 through 10.2 M030 releases.
30
User Interface Customization
Section Changes
User Interface Technology Overview • Windchill Client Architecture
on page 222 Overview on page 223 was updated
in 10.1 M030. It was removed in
10.2 M030.w
• Javascript Functions Overview on
page 238 was updated in 10.2
M030.
• Adding Custom Code to all
Windchill Client Architecture Pages
on page 245; added Color
Customizations in the Reference
Designator Differences Column on
page 246 in 10.1 M020.
Customizing HTML Clients Using the • “Customizing UI Branding” was
Windchill JSP Framework on page 276 updated in 10.1 M030.
• Customizing the UI with Ajax on
page 277
• Split Pane / Two Pane on page 429
was updated in 10.1 M030.
• Updated Customizing the UI with
Ajax on page 277 in 10.1 M010.
• Component Access Control on page
316 was updated in 10.2 M030.
• Configuring the Drag and Drop
Zone
on page 443 was added in 10.2
M030
• Customization Tools Overview on
page 381 was updated in 10.1
M040.
Generic UI Customizations on page • System Banner Alert Message on
446 page 468 was updated in 10.1 M10
and again in 10.2 M030.
Adding Actions and Hooking Them Up • Action Framework for Windchill
in the UI on page 473 Client Architecture on page 474
was updated in 10.1 M010.
Presenting Information in the UI on • The “Generating the Name
page 562 Attribute Server” section was
removed in 10.2 F000.
• Attribute Customization on page
31
Section Changes
615 was updated in 10.2 M030.
• Constructing and Rendering a Table
Using the JSP Framework
on page 564 was updated in 10.1
M030.
• Windchill Client Architecture Tree
on page 599 was updated in 10.1
M030.
• Attribute Customization on page
615 was updated in 10.2 M030.
• Generating the Name Attribute
Server was removed.
• Dynamically Resolved Attributes
for Customizations on page 563
was updated in 10.1 M040 to
remove rich text from list of
standard attribute supported data
types
Constructing Wizards on page 790 • Wizard Processing on page 819 was
updated in 10.1 M010.
• Building Wizards to Create a Single
Object on page 844 was updated in
10.1 M010.
• Building Wizards to Edit a Single
Object on page 866
• Client Generated Form Data on
page 923 was updated in 10.1
M010.
• Wizard Processing on page 819 was
updated in 10.1 M030.
• Client Generated Form Data on
page 923
32
Section Changes
“Customizing Online Help” • “Adding Help Topic to the Help
Center TOC” was added in 10.1
M020. This section was removed in
11.0 M030.
Windchill Search Customization on • Customizing Solr on page 1076 was
page 1073 updated in 10.2 M030.
○ “Custom Solr Help Link” was
updated in Customizing Solr on
page 1076 in 10.2 M010.
• Windchill Search Customization on
page 1073 was added in 10.1 M010.
33
Section Change / Release
Customizing Workflow Administration • Customizing Workflow Task Pages
on page 1269 on page 1294 was updated in 10.2
M030.
• Customizing Change Activity
Workflow Assignments
on page 1340 was added in 10.2
F000.
• Customizing Change Tables
Designed for Workflow
on page 1351 was added in 10.2
M030.
Customizing Security Labels on page • Customizing Security Labels on
1437 page 1438 was updated in 10.2
M030.
Customizing Windchill Visualization • Customizing Publishing Queues
Services on page 1456 on page 1474 was added in 10.2
M030
• Modifying the Default Behavior of
Dynamic Part Generation
on page 1489 was updated in 10.2
M010
Report Generation on page 1492 • Updated the Report Selection List
Customization on page 1548 topic
with information on customizing
the PSB ribbon toolbar in 10.2
M030
Packages Customization on page 1599 • Package Type-Based Properties
on page 1600 was updated in 10.2
F000.
• Identifying Users in Context
Replication and Activating
Replicated Users on page 1614 was
added in 10.2 F000.
• Select Files – Copy Forward
Exclusion Decisions
on page 1628 was added in 10.2
F000.
• Windchill Replication Package
Command Line Sample Scripts
on page 1631 was added in 10.2
F000.
DTI Customization Framework on page • Add Custom Attributes to Microsoft
1678
34
Section Change / Release
Office on page 1679 was updated in
10.2 M030.
• Customize Windchill Actions in
Windows Explorer on page 1696
was updated in 10.2 M010 and
M030..
Data Exchange using Standards in • The “AP214 AIM Mapping”
Windchill section was removed in 10.2 M010.
on page 1788. This chapter was • STEP Data Exchange using
renamed from “STEP Support in EXPRESS on page 1790 was added
Windchill” in 10.2 M020. in 10.2 M010. It was further
updated in 10.2 M030.
• PLCS Data Exchange on page 1966
Windchill Workgroup Manager This chapter was added in 10.2 M030
Customization on page 1984
Customizing Action Item Attributes on This chapter was updated in 10.2 F000.
page 1742
35
Chapter Section
Enumerated Types on page 2203 • External Enumerated Value Lists
on page 2214 was added in 10.2
F000
Customizing Modeled Elements on • Customizing Column Lengths on
page 2280 page 2281 was updated in 10.1
M030
• How to Write an IX Application on
page 2391 was updated in 10.2
F000
• How to Write Exp/Imp Handlers on
page 2407 was updated in 10.2
F000
• Adding Export Functionality in the
Project Plan Table
on page 2449 was added in 10.1
M020
36
1
Windchill Customization Basics
Configuration Options ................................................................................................40
Customizations .........................................................................................................43
Windchill Customization Points...................................................................................46
Directory Structure ....................................................................................................49
Environment Variables ...............................................................................................55
Property Files............................................................................................................56
Properties and Property Files .....................................................................................60
Example Overview ....................................................................................................65
Windchill Development Environment...........................................................................66
Customization Setup .................................................................................................67
Creating the Class .....................................................................................................68
Creating a UI.............................................................................................................77
Customization Notes .................................................................................................98
Windchill Modeling Heuristics ................................................................................... 101
Windchill Foundation Abstractions ............................................................................ 104
Setting Up a Directory Structure for Managing Customized Files and Text
Tailoring .............................................................................................................. 110
Best Practices for Customizing Files Supplied by PTC ............................................... 118
Best Practices for Adding New Packages and Files.................................................... 137
Monitoring a Customized Windchill Environment........................................................ 140
Customization with Windchill Queues........................................................................ 141
Customizations with Log4j 2.0 .................................................................................. 142
Using the xconfmanager Utility ................................................................................. 151
Formatting Property Value Guidelines ....................................................................... 163
About the windchill Command .................................................................................. 163
Windchill Shell ........................................................................................................ 166
Tutorial Overview .................................................................................................... 168
Create Administrator and User ................................................................................. 172
Create a Library and Document ................................................................................ 182
Allocate Database Columns for Local Attributes......................................................... 188
Create a New Attribute Definition and Add it to the Document Type ............................. 191
37
As the End User, Create a Document with the new Attribute ....................................... 198
Create a Document Subtype .................................................................................... 201
Create an Instance of the New Document Subtype .................................................... 205
Model a New Document Subclass ............................................................................ 206
Create an Instance of the New Document Subclass ................................................... 213
Verify the Customizations......................................................................................... 216
Customization Tutorial Summary .............................................................................. 217
Example: Create a modeled Object with Derived Attributes from modeled Master
Class .................................................................................................................. 217
38 Customization Guide
2
Customization Overview
Configuration Options ................................................................................................40
Customizations .........................................................................................................43
Windchill Customization Points...................................................................................46
The Windchill solutions are designed to fit the needs of customers in different
industries and of different sizes. The Windchill solutions are built to enable
product development business processes. Input for these solutions comes from the
many PTC customers who are leaders in their domains and from PTC industry
experts.
In order to reduce the cost of ownership, the Windchill solutions provide extensive
out-of-the-box capabilities and configuration options to make them easily
adaptable to these disparate customers and their different product development
processes and needs.
Where the configuration options do not provide sufficient flexibility and no
appropriate out-of-the-box capabilities are available to satisfy a particular business
need, Windchill provides an extensive set of customization features that customers
can leverage to satisfy such business needs.
39
Configuration Options
Properties and Preferences
Windchill provides an extensive set of options that control how the system
behaves, how the user interacts with the system, or how the system presents itself
to the user. These options are either properties or preferences.
Properties
Properties are created in text files in the Windchill codebase and control overall
system configuration. For example, the wt.home property contains the path to
the installation directory. Properties are stored in files with the .properties
extension. Changing most properties requires a restart of the Windchill method
server.
See Property Files on page 56 for some additional information on property files. A
complete set of properties and descriptions for the wt.properties,
tools.properties, and db.properties files can be found in the
properties.html file in the Windchill codebase directory.
Preferences
Preferences are set through the Windchill user interface and do not require a
server restart. They control application behavior (for legacy reasons, some
Properties also control application behavior). Preferences can be implemented on
different levels of detail. Preferences can be configured to control the whole
Windchill installation, or can be used more narrowly to control an organization’s
or an application container’s (e.g. Product, Library), or a specific user’s setup.
See Preference Framework on page 459 for some additional information on
preferences.
The table below provides just a few of the available preferences:
Preference Description
Change Notice without Change Request Allows creating a change notice
without a change request.
Enable Structure Propagation Enables propagation of effectivity
statements down a product structure.
40 Customization Guide
Preference Description
Digest Notification Schedule Set up a schedule for Digest
Notification. That is, instead of sending
individual notification of as events of
interest to a user happen, the system
will collect and send all notifications in
one email according to the
administrator-setup schedule.
Display Thumbnails Controls whether the thumbnail action
available in tables.
Workflow Templates
Windchill provides a very powerful workflow configuration and execution engine.
The workflow engine of Windchill can model virtually any business process
which can be modeled via an easy-to-use drag-and-drop tool.
The workflow engine has an embedded java virtual machine which allows a
business analyst to embed java expressions and process logic where appropriate.
For more information on workflow templates see the online help topic
“Customizing Workflow Administration” in the Windchill Help Center.
Customization Overview 41
Soft Typing
• Soft Typing is the name of the set of Windchill capabilities that allows a
customer to, at runtime, add additional types and attributes to the out-of-the-
box Windchill Schema. This is done without having adding additional tables
to the database, without restarting the database, and without restarting the
system.
• With the Soft Typing capabilities, customers can add data types and meta data
attributes that are meaningful to them and which are necessary for their
business processes. For all intents and purposes, these customer-defined types
are no different than any other out-of-the-box object in the system: Types can
assigned access control rules, can be assigned workflows and lifecycles, can
be assigned custom UIs, can have Object Initialization Rules assigned to them,
are accessible via APIs, etc.
No user interface modifications are necessary as the Windchill user interfaces
automatically accommodate (e.g. adapt to) these additional Types and Attributes.
The general guideline to be followed is this: If a need can be satisfied by soft
typing, then it should. That is, do not customize (i.e. create modeled extensions) to
the out-of-the-box schema. The reason for this rule is to minimize the total cost of
ownership of Windchill and minimize upgrade costs and burdens. This, in no way,
is a limitation on the customizability of Windchill; but, rather, the intent of the
rule is to reduce the cost of ownership.
42 Customization Guide
Customizations
Windchill is an open system that is fully supports customizations at the schema,
server, and UI levels. An extensive set of APIs are published, documented, and
supported to enable these customizations. But as stated above, in order to reduce
the cost of ownership, if changing other mechanisms such as properties or
preferences satisfy the business need, then customizations should not be used.
Service Customizations
Windchill supported server-side customizations to enable certain business
processes or enforce business constrained. Any kind of customization can be
performed. The most common types of customizations falls into one of the
following categories:
• Process form data submitted through the user interface
• Validate data - (e.g. Do not allow the user to enter a Need Date for a Change
Request that is more than 30 days into the future)
• Implement service listeners - (e.g. Create a listener that waits for any data to
be checked in and populate an MRP system with appropriate data)
• Get/Put data in an external systems - (e.g. when the user navigates to a part’s
details, get the cost of the part from the ERP system and display it in the same
UI)
Customization Overview 43
User Interface Customizations
The Windchill Client Architecture is a Windchill-aware JSP framework. It
provides very high-level building blocks known as common components which
make Windchill UI development a very efficient process done with ease.
Javadoc and learn-by-example documentation is available to reduce the learning
curve and increase developer productivity.
For more information on user interface customizations, see Generic UI
Customizations on page 446.
Info*Engine
Info*Engine provides data access and integration capabilities to access Windchill
data, remote Windchill systems and non-Windchill data and services (through
adapters). Info*Engine components can be used in many different software and
hardware configurations to meet your business requirements for accessing,
managing, and presenting data from many different information systems.
All basic Info*Engine solutions take advantage of five fundamental concepts: JSP
pages, tasks, webjects, groups, and the virtual database. Both JSP pages and tasks
are text-based documents that define how Info*Engine either displays or retrieves
information. Webjects are the means by which Info*Engine JSP pages and tasks
gather, manipulate and display data. Groups are the chunks of information
generated and manipulated by JSP pages and tasks. The virtual database (VDB) is
the special holding area where groups are stored until they are manipulated or
passed along by JSP pages and tasks.
• For general information on Info*Engine, see Info*Engine User's Guide.
• For information on Info*Engine customizations, see Managing Windchill Info
Engine Tasks on page 122.
Custom Reports
Windchill provides predefined, out-of-the-box reports in the areas of change
management, project item status, and parts/products. Your company-specific
custom reports can be created using Windchill Query Builder or the Windchill-
integrated third-party report authoring tool, Cognos.
Use Windchill Query Builder if you would like to create very simple tabular
reports and your site is not configured for third-party reporting tool, Windchill
Business Reporting.
Windchill Business Reporting (WBR) is a new reporting framework that embeds
Cognos Business Intelligence (BI) within Windchill to provide out-of-the-box
integration between Windchill and Cognos BI. It also includes pre-built reports on
change management, project items status, and parts/products.
44 Customization Guide
To create tabular reports, visual and graphical reports, dashboard reports, and
drill-down reports, use the optional third-party reporting authoring tool. This
optional authoring tool also allows you to modify out-of-the-box reports. Using
the authoring tool you can create new reports that include charts and graphs
(Crosstabs, bar/3D bar, pie, gauge, funnel, scatter and more). The report data
sources that are required for creating custom reports in report author tool can be
created using Info*Engine report tasks and Query Builder templates.
For more information on custom reports, see Report Generation.
Customization Overview 45
Windchill Customization Points
Windchill is composed of thousands of Java classes. To help you focus your
customization efforts, certain Windchill Java classes have been designated as
belonging to the Windchill Supported API. To customize Windchill, you should
interact only with the classes in the Windchill Supported API. The Javadoc
provided with Windchill defines the Supported API.
46 Customization Guide
If a class (or method) is flagged as Supported: true, it indicates that the class
or method may be referenced by customized code. If a class is flagged as
Extendable: true, it indicates that the class may be extended. For example,
WTPart is both Supported and Extendable, as shown in the following illustration.
The fact that a class is part of the Supported API indicates that some part of it is
meant to be used, or at least understood by customizers. The Javadoc for some
classes is distributed for information purposes (and if that is the case, it should be
clear from the Javadoc). A class is meant to be extended only if its Javadoc
contains the line indicating “Extendable: true”. (Classes that can be extended are
listed in Appendix B, Extendable Classes in the Windchill Supported API.)
Methods and other programming elements may also have a “Supported API” line
in their Javadoc. If a class is not part of the Supported API, then neither are any of
its methods. If a class is part of the Supported API, that does not indicate that its
methods are, too. For a method to be part of the Supported API, its Javadoc must
also state “Supported API: true”.
Customization Overview 47
3
The Windchill Development
Environment
Directory Structure ....................................................................................................49
Environment Variables ...............................................................................................55
Property Files............................................................................................................56
Properties and Property Files .....................................................................................60
48 Customization Guide
Directory Structure
The image below shows the Windchill directory structure after you install all
available components. If Windchill was installed as recommended to follow this
structure, go to the home directory where Windchill is installed and navigate
through this structure as it is described here.
50 Customization Guide
Contains files for customizations, and rbInfo files for text.
srclib
Contains module jar files.
step
Contains STEP application related files.
taskeditor
Contains the Info*Engine task editor startup scripts, help files reside and is the
runtime directory for the task editor.
tasks
Contains Info*Engine tasks.
tomcat
Embedded Servlet Engine (based on Tomcat) installation.
temp
Temporary files used by Windchill.
Upgrade
Contains files to facilitate the upgrade process.
utilities
Contains various Windchill utilities.
vaults
Default file vault location.
WHC
Contains the Windchill Help Center which consists of the online help.
WinDU
Directory of xml files that declare the existence of tasks that are executable by the
Windchill Diagnostic Utility.
The codebase directory and src directory are described in more detail in the
following subsections.
52 Customization Guide
Note
To allow presentation in manual format, many subdirectories in the wt
directory are not included in this figure.
54 Customization Guide
Environment Variables
The environment variables required for running Windchill tools and utilities will
be defined by starting a Windchill shell. The Windchill shell is described in more
detail in Windchill Utilities on page 150.
56 Customization Guide
This is an abbreviated form of the file that is in codebase.
(Care must be taken when using a manually created classpath that includes
both codebase and System Generation jars, since properties files will be
loaded based on the order of the classpath components.)
The following sections discuss only a subset that you as a developer are most
likely to be interested in. A complete set of properties and descriptions for the wt.
properties, tools.properties, and db.properties files can be found in the properties.
html file in the codebase directory.
wt.properties file
To use Windchill, the following properties must be set in the wt.properties file
(this is usually done at installation). Note that you must use double back slashes to
specify path names in the wt.properties file. This is necessary because the string is
read by a Java program.
• wt.home, which specifies the top level of the class directory structure where
Windchill is installed. The default value is c:\\windchill.
• wt.server.codebase, which is used by client applications. It specifies a URL
from which client applications can download server resources such as property
files. Server applications may use this property when writing dynamically
generated HTML to be returned to a client browser. It is used to build URLs
for static resources such as images or HTML files that reside under the
server’s codebase directory.
• java.rmi.server.hostname, which specifies a host name used to identify the
server host. It is used by the Java RMI runtime for clients to look up the IP
address of the server. It can be specified as a symbolic name, such as a fully-
qualified Internet domain name, or numerically in dot notation (for example,
127.0.0.1). If not specified, the RMI runtime will use the name returned by
InetAddress.getLocalHost() method, which may return a name that is not
known to remote clients. We recommend that this property be set to the fully-
qualified Internet domain name of the server host.
You may also want to set the following properties:
• wt.access.enforce
This property enforces access control. By default. it is true. However, if you
are debugging and want to bypass access control temporarily, you can set it to
false.
• wt.logs.enabled
This property enables and disables logging in applications that support it, such
as the Windchill Server Manager and Method Server applications. By default,
it is false. To write debugging messages to a log file, you must set it to true.
• wt.method.verboseClient and wt.method.verboseServer
service.properties file
The service.properties file contains properties used by the Windchill service
delegate mechanism. This mechanism is a general facility for adding delegate
classes to an existing service to implement new, customized behavior. In this
context, service can mean any sort of Java mechanism that provides functionality
to other classes.
For example, assume a copy service exists that can make copies of certain classes
of objects. The service knows how to make copies only for objects of certain
classes: the classes for which copy service delegates have been created. Each
delegate implements an interface, defined as part of the copy service, that contains
the methods needed by the service. Once the delegate is created and put in the
codebase, the copy service is notified of its existence by adding an entry to the
service.properties file.
Generally, each service is accessed using a factory. The factory either returns
instances of delegates to perform services on particular classes of objects, or it
performs the operations on the objects itself by instantiating the necessary
delegates internally.
If a Windchill service supports customization by adding delegates, the description
of how to do the customization is described elsewhere in the documentation.
tools.properties file
• wt.generation.sql.dir, which specifies where SQL scripts will be generated.
• wt.generation.sql.xxxTablesSize, which sets default sizes for tables.
Note
Because tools.properties is contained within the SystemGeneration.jar, user
overrides to these properties are placed in codebase\user.properties.
58 Customization Guide
user.properties file
The user.properties file contains user overrides that are used by the System
Generation tools.
Note
Configuration overrides for System Generation should be configured in user.
properties using the xconfmanager utility.
db.properties file
The db.properties file contains properties that are used by the Windchill
persistence layer to access the database. They can be set in the wt.properties file
but are usually kept in a separate file identified by the wt.pom.properties entry.
Because a password is contained in this file, you should maintain it in a secure
location. The values in the separate file override the values in the wt.properties
file.
In the db.properties file, you must set the following properties:
• wt.pom.dbUser, which specifies the Oracle user name you or your Oracle
administrator defined for you. This user is the owner of Windchill tables and
stored procedures. There is no default; it must be set.
• wt.pom.dbPassword, which specifies the Oracle password you or your Oracle
administrator defined for you. There is no default; it must be set.
• wt.pom.serviceName, which is the service name you or your Oracle
administrator created. There is no default; it must be set.
The first format is used to locate a Java service or delegate class to perform a
function or provide a service. The second format is used to locate a resource file
— for example, a HTML template file or an icon image file
60 Customization Guide
Definitions
• Service Type = the type of service or delegate referenced by this property
• Resource Type = the type of resource referenced by this property
• Selector = an identifier used to specify the context in which this service or
resource is to be used (for example, an action name)
• Requestor = the object class for which the service, delegate, or resource is to
be used
• Service Priority Number = a priority rating used to choose between valid
delegates (see below)
• Service Class Name = name of delegate or service class for the given Service
Type, Selector, and Requestor
• Resource Name = name or resource for given Resource Type, Selector, and
Requestor
• Duplicate or singleton = a flag to indicate whether the server should instantiate
a shared instance of a delegate class or create a new one for each use. If
neither is specified, duplicate will be used.
This is an example property for a template processor:
wt.services/svc/default/wt.enterprise.TemplateProcessor/AddAlternates/
wt.part.WTPartMaster/0=wt.part.AlternatesLocalSearchProcessor/duplicate
where
Service Type = "wt.enterprise.TemplateProcessor"
Selector = the action name "AddAlternates"
Requestor = "wt.part.WTPartMaster"
Note
Any service class that incorporates an HTTPState object should be made
duplicate. This would include instances of BasicTemplateProcessor,
and FormTaskDelegate, NavBarActionDelegate.
If a factory receives a request for a service or resource class for a given requestor
object class but no property entry for that requestor class is found, the factory will
attempt to find an entry for the parent class or interface of the requestor class. If
no entry for the parent class or interface is found, a search will be made for an
entry for the parent of the parent or interface, and so on. It could happen that
entries for two or more parent classes or interfaces are found. If the entries have
different service priority numbers, the one with the lowest number will be
selected. If the entries have the same service priority number, the one selected is
arbitrary.
Property files will be loaded in the order listed, and files listed for
defaultPropertyFiles will be loaded before those for
customPropertyFiles. If the same property is found in more than one file,
the value for the one loaded last will be used. Any custom properties should be
placed in the latter list.
Except for the need to separate application context service properties from
ordinary properties and the effect of load order, the grouping of properties into
various properties files is unimportant to the system and based primarily on ease
of maintenance. If a TemplateProcessor property is put in the
htmltemplate.properties file instead of service.properties the system
will still find it.
Many of the more heavily customized service property files are not created or
edited directly but instead are generated from xml files. XML files used to
generate property files have the same name as the associated property file but
have the additional extension “.xconf”. For example, the XML file used to
generate service.properties is called service.properties.xconf.
See Managing Customizations on page 109 for more information on xconf files.
If you need to add application context property entries for your custom HTML
clients, we recommend you put them in a new properties file or files used only for
your customizations. This file should be added to the list of files for
WTServiceProviderFromProperties.customPropertyFiles using
the xconfmanager utility. This procedure is described in Managing Customizations
on page 109 .
62 Customization Guide
• wt.services.applicationtext.TypeBasedService
ProviderFromProperties.
CustomPropertyFiles
If you need to add typed service property entries for your custom HTML clients,
we recommend you put them in a new properties file or files used only for your
customizations. This file should be added to the list of files for
TypeBasedServiceProviderFromProperties.CustomProperty
Files using the xconfmanager utility. This procedure is described in Managing
Customizations on page 109.
64 Customization Guide
Example Overview
The customization will introduce a new class, Pet. Pet will represent an animal (a
pet) and will define the following properties:
• name the name of the pet
• kind an enumeration consisting of dog, cat, gerbil, etc.
• dateOfBirth a date represeting the pet’s birthday
• fixed a boolean indicating whether the pet has been spayed or neutered.
Additionally, the Pet will incorporate the following:
• ContentHolder (a domain interface) to store pictures of the pet
• Ownable (a domain interface) to support assigning the pet to an owner
• WTObject (a base class) to provide basic functionailty.
Pets can be stored in the Windchill database and support basic “CRUD”
operations (Create, Read (query), Update, Delete). Additionally, the Windchill
user interface will be augmented to support CRUD operations against pets in the
browser. Note that the Pet example is not intended to be “complete”, nor is it an
example of a practical customization; it merely demonstrates a simple Windchill
customization introducing a new, persisted, and very basic class.
66 Customization Guide
Customization Setup
Setup consists of two steps:
1. Start a Windchill shell
2. Install & configure Eclipse.
68 Customization Guide
The result will be an empty class, as follows:
This is expected.
c. Resolve them by:
i. Making Pet extend _Pet.
ii. Adding the required declaration to Pet’s body
d. Save Pet again. Pet now extends _Pet, which implements
wt.fc.Persistable, resulting in two new errors.
f. Create the no-argument factory method for Pet, which consists of the
following:
public static Pet newPet() throws WTException {
final Pet instance = new Pet();
instance.initialize();
return instance;
}
70 Customization Guide
following (the annotation’s closing parethensis is shown): properties=
{ })
b. All properties will be included between the “{}”s for properties, each on
their own line. First, add name as follows:
@GeneratedProperty(name="name", type=String.class,
columnProperties=@ColumnProperties(index=true),
constraints=@PropertyConstraints(required=true, upperLimit=
60))
This property declares name, of type String. The name is required,
must be 60 characters or less in length, and will be indexed in the database.
Most of this can be code-completed by the IDE, reducing significantly the
amount of effort needed to enter it
c. Next, add dateOfBirth immediately following name. It will be
necessary to add a comma to the previous line to separate the two
declarations:
@GeneratedProperty(name="dateOfBirth", type=Timestamp.class)
Here, dateOfBirth is a java.sql.Timestamp.
d. Finally, add fixed (a boolean): @GeneratedProperty(name=
"fixed", type=boolean.class)
6. Create PetKind, an enumerated type consisting of common pet kinds.
a. Navigate to File ▶ New ▶ Class.
b. Set Package to com.acme
c. Set Name to PetKind
d. Click Finish.
Add the GenAsEnumeratedType annotation to the class declaration and
make the class extend _PetKind (ignore the warning). The result will look as
follows:
dog.value=Dog
dog.order=10
cat.value=Cat
cat.order=20
gerbil.value=Gerbil
gerbil.order=30
8. Add kind to Pet.
a. Place kind between name and dateOfBirth:
@GeneratedProperty(name="kind", type=
PetKind.class, constraints=
@PropertyConstraints(upperLimit=40))
The stored value of an enumerated type is the key value (dog, cat, gerbil)
as opposed to the display value (Dog, Cat, Gerbil). An upper limit of 40
was specified as it’s a more than sufficient value to store the keys.
9. Verify the result. Note that, as a minor clean-up, all the separate annotations
imports have been reduced to a single “*” import:
72 Customization Guide
a. Find or start a Windchill shell (command assumes shell is in Windchill
directory).
b. Run the following command: ant -f bin/tools.xml bundle
-Dbundle.input=com.acme.*
11. Ensure Pet, PetKind compile with Ant.
a. Reuse Windchill shell from previous command
b. ant -f bin/tools.xml class -Dclass.includes=com/
acme/** -Dclass.force=true
12. Generate SQL scripts.
a. Reuse, again, Windchill shell
b. ant -f bin/tools.xml sql_script -Dgen.input=
com.acme.*
13. Load schema for Pet.
a. Locate, under load point/db, Make_pkg_acme_Table.sql.
i. Oracle (single byte): db/sql/com/acme/Make_pkg_acme_
Table.sql
ii. Oracle (multi-byte): db/sql3/com/acme/Make_pkg_acme_
Table.sql
iii. SQLServer: db/sqlServer/com/acme/Make_pkg_acme_
Table.sql
b. cd to the db/<xxx> directory from above (db/sql, db/sql3, or db/
sqlServer)
c. Run the script
i. Oracle: sqlplus <database credentials> @com/acme/
Make_pkg_acme_Table.sql
ii. SQLServer: …
d. Repeat for @com/acme/Make_pkg_acme_Index.sql
74 Customization Guide
cat = Pet.newPet()
cat.setName('Stimpy')
cat.setKind(PetKind.toPetKind('cat'))
cat.setDateOfBirth(Timestamp(SimpleDateFormat('yyyy-MM-dd').
parse('1996-08-24').getTime()))
cat.setFixed(False)
cat = PersistenceHelper.manager.store(cat)
3. Update the cat (note that “#” starts a comment and is equivalent to Java’s “//”;
the comment string need not be entered and is intended to highlight that the
call will print the current principal):
cat.setFixed(True)
cat = PersistenceHelper.manager.modify(cat)
cat = OwnershipHelper.service.takeOwnership(cat)
OwnershipHelper.getOwner(cat) #Should print/return the current
principal
4. Query (read) for the Pets named Fergus:
qs = QuerySpec(Pet)
qs.appendWhere(SearchCondition(Pet, Pet.NAME, SearchCondition.
EQUAL,
'Fergus'))
qr = PersistenceHelper.manager.find(qs)
qr.size() #Should print/return 1
fergus = qr.nextElement()
fergus.getName() #Should print/return “Fergus”
5. Finally, delete the dog:
PersistenceHelper.manager.delete(dog)
76 Customization Guide
Creating a UI
So far, Jython has stood in for a real client. Windchill, as a web application,
utilizes the browser to provide a user interface. The following user interface
components will be created for Pet:
• A table to display all pets, which will be linked to from the Site ▶ Utilities page
• A pop-up to create new pets (with support for uploading pictures (content))
• A similar pop-up to edit existing pets
• An “info” page to view pets, with an “Attachments” tab to download pictures
• Actions to create, edit, and delete pets
Pet Table
1. Create the PetTable class
a. File ▶ New ▶ Class
b. Set Package to com.acme.mvc.builders
c. Set Name to PetTable
d. Set Superclass to AbstractComponentBuilder (from com.ptc.mvc.
components)
e. Click Finish
2. AbstractComponentBuilder requires that two methods be
implemented (Eclipse will generate method stubs for each). The first,
buildComponentData, should return the objects (rows) to display in the
table. Replace the method’s body with the following code to simply query all
pets:
return PersistenceHelper.manager.find(new QuerySpec(Pet.class));
@RBUUID("com.acme.jca.acmeActionResource")
public final class acmeManagerResource extends WTListResourceBundle {
@RBEntry("Pets")
public static final String PET_TABLE_LABEL = "pet_table_label";
}
78 Customization Guide
i. Make the project’s .classpath (eclipse/cust_Windchill_src/
.classpath) writeable
ii. Project ▶ Properties
iii. Select Java Build Path and the Source tab.
iv. Select Excluded under cust_Windchil_src/src and select Edit.
v. Select config/** and select Edit.
vi. Replace config/** with config/logicrepository/** and
click OK
vii. Click Finish and OK
7. Create a new file named Pet-configs.xml.
a. File ... ▶ Other ▶ Other
b. Select XML ▶ XML File, then Next (if XML/XML File are not available,
install Eclipse XML Editors and Tools, which is available under the Web,
XML, and Java EE Development category when working with the Helios
software site -or- simply create a General -> File)
c. Assign parent folder to cust_Windchill_src/src/config/mvc
and file name to Pet-configs.xml and click Finish
d. Content is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.ptc.com/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-
2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-
2.5.xsd
http://www.ptc.com/schema/mvc http://www.ptc.com/schema/mvc/
mvc-10.0.xsd">
<!-- Define the builders -->
<bean class="com.acme.mvc.builders.PetTable"/>
</beans>
80 Customization Guide
c. After ResourceBundle enterpriseRb =
ResourceBundle.getBundle(ENTERPRISE_RESOURCE,
localeBean.getLocale()); add ResourceBundle acmeRb =
ResourceBundle.getBundle(ACME_RESOURCE,
localeBean.getLocale());
ResourceBundle objectRb = ResourceBundle.getBundle
(OBJECT_CONFIG_RESOURCE, localeBean.getLocale());
ResourceBundle enterpriseRb = ResourceBundle.getBundle
(ENTERPRISE_RESOURCE, localeBean.getLocale());
ResourceBundle acmeRb = ResourceBundle.getBundle(
ACME_RESOURCE, localeBean.getLocale());
d. After "PERSONAL_CABINETS” , add "PET_ADMINISTRATION" ,
String [] knownUtilities={"AUDITING_PURGE",
"AUDITING_LICENSE_USAGE",
"AUDITING_ORGANIZATION_USAGE",
"AUDITING_SECURITY_REPORT_
QUERIES",
"AUDITING_SECURITY_REPORTS",
"CALENDAR_MANAGEMENT",
"CLASSIFICATION_ADMINISTRATOR",
"SCMI_ADAPTER_ADMINISTRATOR",
"SCMI_ADMINISTRATOR",
"CONFIGURATION_FILE_GENERATOR",
"ESI_TRANSACTION_ADMIN",
"REPLICATION_ADMINISTRATOR",
"CCS_MANAGER",
"IMPORT_EXPORT",
"INFO_ENGINE" ,
"NUMBERING_SCHEMES",
"VERSIONING_SCHEMES",
"LIFE_CYCLE_ADMIN",
"ESI_DISTRIBUTION_TARGET_ADMIN",
"OPTEGRA_GATEWAY",
"RULES_ADMINISTRATION",
"PACKAGES_MAPPING_MANAGER",
"PARTICIPANT_ADMINISTRATION",
"PERSONAL_CABINETS" ,
"PET_ADMINISTRATION",
e. After the if (wvs_enabled ) { block add linkDatum.put("PET_
ADMINISTRATION.isUtilityInstalled", "Yes");
if (wvs_enabled ) {
linkDatum.put("CAD_AGENT.isUtilityInstalled"
, "Yes" );
linkDatum.put("PRODUCT_VIEW.isUtilityInstalled"
, "Yes" );
linkDatum.put("PUBLISH_MONITOR.isUtilityInstalled"
, "Yes" );
linkDatum.put("PUBLISH_SCHEDULER.isUtilityInstalled"
, "Yes" );
linkDatum.put("PET_ADMINISTRATION.isUtilityInstalled",
"Yes");
f. After linkDatum.put("AUDITING_SECURITY_
REPORTS.isAuditUtility" , "Yes" ); add // set ACME
utility flag. Define only if the utility is considered
an ACME utility linkDatum.put("PET_
ADMINISTRATION.isACMEUtility", "Yes");
// set audit utility flag. Define only if the utility is
considered an
// auditing utility
linkDatum.put("AUDITING_PURGE.isAuditUtility"
, "Yes" );
linkDatum.put("AUDITING_ORGANIZATION_USAGE.isAuditUtility"
, "Yes" );
linkDatum.put("AUDITING_LICENSE_USAGE.isAuditUtility"
, "Yes" );
linkDatum.put("AUDITING_SECURITY_REPORT_QUERIES.
isAuditUtility", "Yes" );
linkDatum.put("AUDITING_SECURITY_REPORTS.isAuditUtility"
, "Yes" );
82 Customization Guide
, linkBean.getLinkID(null,"textLink:cadAgentAdmin") );
linkDatum.put("CALENDAR_MANAGEMENT.idText"
, linkBean.getLinkID(null,"textLink:calendarManagement")
);
linkDatum.put("CLASSIFICATION_ADMINISTRATOR.idText"
, linkBean.getLinkID(null,"textLink:
classificationAdministrator") );
linkDatum.put("CONFIGURATION_FILE_GENERATOR.idText"
, linkBean.getLinkID(null,"textLink:
configurationFileGenerator") );
linkDatum.put("ESI_DISTRIBUTION_TARGET_ADMIN.idText"
, linkBean.getLinkID(null,"textLink:ESI_DISTRIBUTION_
TARGET_ADMIN") );
linkDatum.put("ESI_TRANSACTION_ADMIN.idText"
, linkBean.getLinkID(null,"textLink:ESI") );
linkDatum.put("EXTERNAL_STORAGE.idText"
, linkBean.getLinkID(null,"textLink:externalStorageAdmin")
);
linkDatum.put("IMPORT_EXPORT.idText"
, linkBean.getLinkID(null,"textLink:importExportAdmin") );
linkDatum.put("PACKAGES_MAPPING_MANAGER.idText"
, linkBean.getLinkID(null,"textLink:
packageMappingManager") );
linkDatum.put("INFO_ENGINE.idText"
, linkBean.getLinkID(null,"textLink:infoEngineAdmin") );
linkDatum.put("LIFE_CYCLE_ADMIN.idText"
, linkBean.getLinkID(null,"textLink:
lifeCycleTemplateAdmin") );
linkDatum.put("NUMBERING_SCHEMES.idText"
, linkBean.getLinkID(null,"textLink:
numberingSchemesAdmin") );
linkDatum.put("POLICY_ADMINISTRATOR.idText"
, linkBean.getLinkID(null,"textLink:policyAdmin") );
linkDatum.put("PERSONAL_CABINETS.idText"
, linkBean.getLinkID(null,"textLink:deletedUsersCabinets")
);
linkDatum.put("PET_ADMINISTRATION.idText"
, linkBean.getLinkID(null,"textLink:petAdmin") );
h. After linkDatum.put("VIEW_NETWORK.pageLoc" ,
viewAction.getActionUrl(actionBean, linkBean,
objectBean, localeBean, urlFactoryBean,nmcontext,
sessionBean,request)); add //ACME pageLocs
linkDatum.put("PET_ADMINISTRATION.pageLoc",
NetmarketURL.convertToShellURL("ptc1/comp/
acme.pet.table"));
//We need to get the locale specific link for the network
admin .
//ACME pageLocs
linkDatum.put("PET_ADMINISTRATION.pageLoc",
NetmarketURL.convertToShellURL
("ptc1/comp/acme.pet.table"));
i. After linkDatum.put("NUMBERING_SCHEMES.urlPrarms"
,"'NumberingSchemes','resizable=yes,scrollbars=
yes,menubar=yes,toolbar=yes,location=yes,status=
yes'"); add linkDatum.put("PET_
ADMINISTRATION.urlPrarms" ,"'PetAdmin','resizable=
yes,scrollbars=yes,menubar=yes,toolbar=
yes,location=yes,status=yes'" );
linkDatum.put("ESI_TRANSACTION_ADMIN.
urlPrarms","'ESITransaction','
directories=no,location=no,menubar=no,scrollbars=yes,status=
yes,
toolbar=no,resizable=yes,height=1000,width=1400'" );
linkDatum.put("EXTERNAL_STORAGE.urlPrarms"
,"'ExternalStorage','resizable=yes,scrollbars=yes,menubar=
no,
toolbar=no,location=no,status=yes,height=455,width=640'" );
linkDatum.put("IMPORT_EXPORT.urlPrarms"
,"'_blank','resizable=yes,scrollbars=yes,menubar=no,
toolbar=no,location=no,
status=yes,height=455,width=640'");
linkDatum.put("PACKAGES_MAPPING_MANAGER.urlPrarms"
,"'_blank','resizable=yes,scrollbars=yes,menubar=no,
toolbar=no,location=no,
status=yes,height=500,width=880'");
linkDatum.put("INFO_ENGINE.urlPrarms"
,"'InfoEngine','resizable=yes,scrollbars=yes,menubar=yes,
toolbar=yes,
location=yes,status=yes'" );
linkDatum.put("LIFE_CYCLE_ADMIN.urlPrarms"
,"'LifeCycleAdmin','resizable=yes,scrollbars=yes,menubar=
yes,
toolbar=yes,
location=yes,status=yes'");
linkDatum.put("NUMBERING_SCHEMES.urlPrarms"
,"'NumberingSchemes','resizable=yes,scrollbars=yes,
menubar=yes,
84 Customization Guide
toolbar=yes,
location=yes,status=yes'");
linkDatum.put("PET_ADMINISTRATION.urlPrarms"
,"'PetAdmin','resizable=yes,scrollbars=yes,menubar=yes,
toolbar=yes,
location=yes,status=yes'" );
j. After linkDatum.put("PERSONAL_CABINETS.linkText"
,objectRb.getString(objectResource.PERSONAL_
CABINETS)); add linkDatum.put("PET_
ADMINISTRATION.linkText"
,acmeRb.getString(acmeResource.PET_
ADMINISTRATION));
linkDatum.put("EXTERNAL_STORAGE.linkText"
,objectRb.getString(objectResource.EXTERNAL_STORAGE));
linkDatum.put("IMPORT_EXPORT.linkText"
,objectRb.getString(objectResource.IMPORT_EXPORT));
linkDatum.put("PACKAGES_MAPPING_MANAGER.linkText"
,objectRb.getString(objectResource.PACKAGES_MAPPING_
MANAGER));
linkDatum.put("INFO_ENGINE.linkText"
,objectRb.getString(objectResource.INFO_ENGINE));
linkDatum.put("LIFE_CYCLE_ADMIN.linkText"
,objectRb.getString(objectResource.LIFE_CYCLE_ADMIN));
linkDatum.put("NUMBERING_SCHEMES.linkText"
,objectRb.getString(objectResource.NUMBERING_SCHEMES));
linkDatum.put("PERSONAL_CABINETS.linkText"
,objectRb.getString(objectResource.PERSONAL_CABINETS));
linkDatum.put("PET_ADMINISTRATION.linkText"
,acmeRb.getString(acmeResource.PET_ADMINISTRATION));
k. After linkDatum.put("PERSONAL_CABINETS.linkDesc"
,objectRb.getString(objectResource.PERSONAL_
CABINETS_DESCRIPTION)); add linkDatum.put("PET_
ADMINISTRATION.linkDesc"
,acmeRb.getString(acmeResource.PET_ADMINISTRATION_
DESCRIPTION));
linkDatum.put("EXTERNAL_STORAGE.linkDesc"
,objectRb.getString(objectResource.EXTERNAL_STORAGE_
DESCRIPTION));
linkDatum.put("IMPORT_EXPORT.linkDesc"
,objectRb.getString(objectResource.IMPORT_EXPORT_
DESCRIPTION));
linkDatum.put("PACKAGES_MAPPING_MANAGER.linkDesc"
,objectRb.getString(objectResource.PACKAGES_MAPPING_
MANAGER_DESCRIPTION));
linkDatum.put("INFO_ENGINE.linkDesc"
,objectRb.getString(objectResource.INFO_ENGINE_
DESCRIPTION));
linkDatum.put("LIFE_CYCLE_ADMIN.linkDesc"
86 Customization Guide
<% } else if ("PET_ADMINISTRATION".equals
(knownUtilities[i])) { %>
href="<%=pageLoc%>"
<% }
3. Enable PET_ADMINISTRATION
a. Create the following two directory structures under load point:
wtSafeArea/ptcOrig/codebase/netmarkets/jsp/site
wtSafeArea/siteMod/codebase/netmarkets/jsp/site
b. Copy listUtilities.jspf to both directories just created above.
c. Edit wtSafeArea/siteMod/codebase/netmarkets/jsp/
site/listUtilities.jsp, appending (after line 67) the following
to the enabled:
showUtility.put("PET_ADMINISTRATION" , "Enable");
import wt.util.resource.*;
@RBUUID("com.acme.acmeResource")
public class acmeResource extends WTListResourceBundle {
@RBEntry("ACME Administration")
public static final String ACME_ADMINISTRATION = "acme_
administration";
@RBEntry("Pet Administration")
public static final String PET_ADMINISTRATION = "pet_
administration";
import wt.util.WTException;
import com.ptc.jca.mvc.builders.DefaultInfoComponentBuilder;
import com.ptc.mvc.components.ComponentBuilder;
import com.ptc.mvc.components.ComponentId;
import com.ptc.mvc.components.ComponentParams;
import com.ptc.mvc.components.InfoConfig;
import com.ptc.mvc.components.TypeBased;
@ComponentBuilder(ComponentId.INFOPAGE_ID)
@TypeBased("com.acme.Pet")
public class PetInfoBuilder extends DefaultInfoComponentBuilder
{
@Override
protected InfoConfig buildInfoConfig(final ComponentParams
params)
throws WTException {
final InfoConfig info = getComponentConfigFactory().
newInfoConfig();
info.setTabSet("petDetails");
return info;
}
}
2. Define the petDetails tab set by creating its action model (in config/
actions/Pet-actionmodels.xml).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE actionmodels SYSTEM 'actionmodels.dtd'>
<actionmodels>
<model name="petDetails">
<action name="primaryAttributes" type="object"/>
<action name="attachments" type="object"/>
</model>
</actionmodels>
88 Customization Guide
3. Define the primaryAttributes.
package com.acme.mvc.builders;
import wt.util.WTException;
import com.acme.Pet;
import com.ptc.core.ui.resources.ComponentType;
import com.ptc.jca.mvc.components.
AbstractAttributesComponentBuilder;
import com.ptc.jca.mvc.components.JcaAttributeConfig;
import com.ptc.jca.mvc.components.JcaGroupConfig;
import com.ptc.mvc.components.AttributePanelConfig;
import com.ptc.mvc.components.ComponentBuilder;
import com.ptc.mvc.components.ComponentConfigFactory;
import com.ptc.mvc.components.ComponentId;
import com.ptc.mvc.components.ComponentParams;
import com.ptc.mvc.components.TypeBased;
@ComponentBuilder("primaryAttributes")
@TypeBased("com.acme.Pet")
public class PetInfoAttributesBuilder extends
AbstractAttributesComponentBuilder {
@Override
protected AttributePanelConfig
buildAttributesComponentConfig
(final ComponentParams params)
throws WTException {
final ComponentConfigFactory factory =
getComponentConfigFactory();
group.addComponent(getAttribute(Pet.NAME, factory));
group.addComponent(getAttribute(Pet.KIND, factory));
group.addComponent(getAttribute(Pet.DATE_OF_BIRTH,
factory));
group.addComponent(getAttribute(Pet.FIXED, factory));
}
panel.addComponent(group);
}
return panel;
90 Customization Guide
a. Navigate to File ▶ New ▶ Other... ▶ Select Other ▶ JSP File and then click
Next.
Note
If the option Other... ▶ Select Other ▶ JSP File is not available, install
Web Page Editor. This is available under the Web, XML, and Java EE
Development category when working with the Helios software site. As
an alternative you can also create a general file (Other... ▶ General ▶
File)
<jca:wizard>
<jca:wizardStep action="petDefineItemAttributesWizStep"
type="pet"/>
<jca:wizardStep action="attachments_step" type="attachments"/>
</jca:wizard>
<attachments:fileSelectionAndUploadApplet/>
<%@include file="/netmarkets/jsp/util/end.jspf"%>
import wt.util.WTException;
import com.acme.Pet;
import com.ptc.core.ui.resources.ComponentType;
import
com.ptc.jca.mvc.components.AbstractAttributesComponentBuilder;
import com.ptc.jca.mvc.components.JcaAttributeConfig;
import com.ptc.jca.mvc.components.JcaGroupConfig;
import com.ptc.mvc.components.AttributePanelConfig;
import com.ptc.mvc.components.ComponentBuilder;
import com.ptc.mvc.components.ComponentConfigFactory;
import com.ptc.mvc.components.ComponentId;
import com.ptc.mvc.components.ComponentParams;
import com.ptc.mvc.components.TypeBased;
@ComponentBuilder("acme.pet.SetAttributesPanel")
@TypeBased("com.acme.Pet")
public class PetSetAttributesPanelBuilder extends
AbstractAttributesComponentBuilder {
@Override
protected AttributePanelConfig buildAttributesComponentConfig
(final ComponentParams params) throws WTException {
final ComponentConfigFactory factory =
getComponentConfigFactory();
92 Customization Guide
(ComponentType.WIZARD_ATTRIBUTES_TABLE);
import wt.util.resource.*;
@RBUUID("com.acme.jca.acmeActionResource")
public final class acmeActionResource extends WTListResourceBundle {
@RBEntry("New Pet")
public static final String PET_CREATE_TITLE = "pet.create.title";
@RBEntry("New Pet")
public static final String PET_CREATE_TOOLTIP =
"pet.create.tooltip";
@RBEntry("New Pet")
public static final String PET_CREATE_DESCRIPTION =
"pet.create.description";
@RBEntry("createPackage.gif")
public static final String PET_CREATE_ICON = "pet.create.icon";}
c. Incorporate the action model (pets list) into PetTable (add before
table.setSelectable(true);). Example:
table.setActionModel("pets list");
7. Start/restart Windchill.
a. Verify the New Pet icon is available on the table
b.
94 Customization Guide
c. Click New Pet and verify a pop-up consisting of a wizard with two steps.
Editing Pet
The process of editing a pet is similar to the process of creating one.
1. Copy createPet.jsp
a. Select create.jsp.
b. Right-click -> Copy
@RBEntry("Edit")
public static final String PET_EDIT_PET_TOOLTIP =
"pet.editPet.tooltip";
@RBEntry("Edit")
public static final String PET_EDIT_PET_DESCRIPTION =
"pet.editPet.description";
@RBEntry("edit.gif")
public static final String PET_EDIT_PET_ICON = "pet.editPet.icon";
import wt.fc.Persistable;
import wt.fc.collections.WTCollection;
import wt.util.WTException;import wt.verification.Verifier;
@Override
public boolean verify(WTCollection a_objects) throws
WTException {
96 Customization Guide
return true;
}}
5. Start/restart Windchill
a. Verify that “edit” is available as an action of an “info” page.
2. Start/restart Windchill.
3. Verify that “delete” has been added as an action to the pet table
4. Delete a pet.
Customization Notes
The user interface customization incorporates pets into the Windchill UI. All basic
“CRUD” operations are supported. However, more could be done. For example,
while content was not demonstrated in Jython (and is demonstrated in the UI),
ownership has been ignored and left out of the UI. How to incorporate concepts
like ownership will be covered elsewhere in the guide.
Additionally, both PetInfoAttributesBuilder and
PetSetAttributesBuilder set the group’s label to a hard-coded,
unlocalizable string. To correct that, take a look at setLabel in PetTable, which
does this correctly.
The choice to incorporate the table into Site ▶ Utilities was based on Pet being
neither AccessControlled nor WTContained, making it more like
Windchill’s administrative objects in practice than like the many Windchill
business objects. The manner in which a modeled customization is incorporated
into the Windchill UI is largely dictated by the behavior (as determined by the
domain interfaces it implements and the parent class it extends).
98 Customization Guide
Customizations — Next Steps
The Pet example illustrates a simple “from scratch” modeled customization with
very little (unique/interesting) logic and no (new) associations. There are, not
surprisingly, many different kinds of customizations. Some customizations simply
extend and existing business class to add properties (a customization largely
superseded by Windchill’s soft typing capabilities), some exist to add new
associations to existing business objects, some exist to add validation and other
logic to existing Windchill classes, and so on. The remaining sections will cover
all of the various kinds of customizations, as well as providing greater insight into
this customization.
Foundation Hierarchy
Binary Links
First class objects implement the Persistable interface. As a result, a database table
is generated for each class in which their objects will be stored. The structured
attributes are stored in the database table of their associated first class object. All
persistable objects, plus any structured attributes that must be written into or read
from the database, must implement the ObjectMappable interface.
This chapter describes the best practices that should be used when you are
customizing files that are supplied by PTC or changing configuration settings that
interact with the way PTC delivers software maintenance releases. The chapter
contains information that can help you understand how to structure and maintain
the files you modify or add to your Windchill environment. It also describes the
tools and Windchill Service Pack options that can be used to set up and update
customized files for Windchill maintenance releases.
Note
These recommendations apply to managing the <Windchill> installation
directory (where <Windchill> is the Windchill Services installation
directory). Best practices for products installed into other directories are not
described here.
If the implementation of Windchill at your site involves modifying files
supplied by PTC, it is important to understand that the maintenance
installation process could overwrite any file that is delivered by PTC (except
for the site.xconf file). This includes files that you may have modified
during customization activities.
Note
Most of these directories contain files that you should never modify;
therefore, the directories should not be in the wtSafeArea/siteMod
directory. If you happen to have files in any of these directories, the target
reports that the files were not copied.
The following files in the wtSafeArea/siteMod directory structure are also not
copied to installation directories:
bin/swmaint.xml
codebase/.xconf-target-file-hints
declarations.xconf
site.xconf
For an up-to-date list of files and directory structures excluded when the
installSiteChanges target option is processed, see the output from the
listSiteModExclusions target option (described next).
• listSiteModExclusions – lists the files and directory tree structure
patterns of those files and directories that are excluded when the
installSiteChanges target option is processed.
Note
The following descriptions assume that you have set up your safe area
directory structure, as described in Directory Structure Diagram for
Customized Files and Text Tailoring on page 110.
Use the following procedure to modify a PTC file for the first time:
1. Copy the original version of the PTC file into the proper subdirectory under
the ptcOrig directory. For example, copy:
<Windchill>/codebase/templates
/adcx.html
to:
<Windchill>/wtSafeArea/ptcOrig/codebase/templates/
abcx.html.
2. Also copy the file to the siteMod directory and then make your modifications
to the file that is in the siteMod directory. For example, copy the abcx.html file
as follows and then modify the copied file:
<Windchill>/wtSafeArea/siteMod/codebase/templates/
abcx.html.
3. When you are ready to use the customized files in your <Windchill>
installation directory, copy the customized files into the installation directory.
The script is described in PTC Script for Working with Customized Files on
page 113.
Note
If there is no corresponding file in the ptcCurrent directory, then there are
no updates for the file in the current maintenance release.
You can run the following swmaint.xml script from a Windchill shell to
list the site changes contained in files that are under the wtSafeArea/
siteMod directory:
ant -f bin/swmaint.xml listSiteChanges
Additionally, for other swmaint.xml script target options, see PTC Script
for Working with Customized Files on page 113.
Note
The Windchill Service Pack installer executes this script and target
automatically whenever there is a siteMod directory and you select the
Complete installation type.
Both the Windchill Service Pack installer and patch installer automatically
execute this command to ensure that any updates delivered by PTC are merged
with your site changes in the <Windchill>/wtCustom directory.
Note
When the client JAR files are updated, clients download them from the
Windchill server as the applications detect the previously downloaded JAR
files are out-of-date.
There are two times when you need to ensure that the client JAR files have been
updated by rebuilding the files. Rebuild client JAR files:
• As part of installing a maintenance release.
• When customizations have been made that affect the client JAR files
Note
When updating for a maintenance release, running Windchill Service Pack
installer with the Complete installation type rebuilds all client JAR files as
needed. If you make new customizations or re-install existing customizations
after running this installer, you must manually rebuild the client JAR files.
Most client JARs are maintained through the use of an Ant script, MakeJar.xml,
provided with Windchill. To ensure that the JAR files maintained through the
MakeJar.xml script are updated correctly, you should add the following to the
<Windchill>/codebase/jarContents/Cust.bom:
• Paths for the compiled resources (*.ser and/or *.class files) of the files you
change
• Paths of customized property files
To rebuild the client JAR files that are managed by jarContents and jarManifest
specifications, execute the following command from a Windchill shell:
ant -f codebase/MakeJar.xml custUpdate
Logical JARs
The concept of a “logical” JAR was introduced to Windchill in R7.0. Each logical
JAR is actually composed of four JARs, in addition to any external dependencies
it might have, e.g. to 3rd-party jars. The components of a logical JAR are shown
in the figure below.
In this figure, the bolded labels denote role names for each component JAR
whereas the italicized name denotes the actual name of the JAR. Thus for a logical
JAR named “MyApplet”, for instance, the components would be MyApplet.jar,
MyAppletCust.jar, MyAppletDSU.jar, and MyAppletFCS.jar.
Note
The classloading precendence is from left to right in the figure, so that
customization JARs override DSU JARs, which in turn override original
distribution JARs.
Note
The usage of “DSU” comes from the fact that, pre-R7.0, maintenance releases
to Windchill were delivered in Downloadable Software Updates.
Note
The figure and the table following it constitute merely a representative view,
not necessarily the complete dependency graph.
Each label refers to a logical JAR (composed of head, customization, DSU, and
FCS components) unless otherwise noted. Bolded labels are “root” JARs intended
as top-level JARs to directly support applets, whereas the non-bolded labels are
Note that wt.jar and 3rdparty.jar, the JARs used in Windchill applet deployments
prior to R7.0 are not used at all by the new applet deployments. Both of these
JARs are now the sole province of any applications which use them to maintain
and use as they see fit. The new JARs are dramatically smaller than wt.jar.
Caution
As a general rule, customizers should not use this command pattern, as it will
rebuild the FCS jars and cause unnecessary downloads by clients that have
already downloaded the FCS jars by this point. Instead, 'custUpdate' and
'dsuUpdate' targets, as described in the following sections, should be used.
If you are using Java 2 v1.4.x, then any resources listed in a .includes file which
are not present in your codebase will result in an error. To remove any such
resources from your .includes files, add the following to your MakeJar.xml
command line:
-DremoveStaleEntries=true
Although it takes only a couple minutes or so to rebuild all client JARs, in most
cases you are only testing an applet or two at a time. In this case you will wish to
the faster Ant targets for individual applets. For instance, to rebuild all JARs
loaded by a workflow applet, one would use (all on one line):
ant -f MakeJar.xml buildFullClientJars -DlogicalJarNames=wtWork
Note
To use the utility, you must be using the Apach Web server.
3. In a separate browser window, start to the applets you want to test and
complete your testing.
4. Return to the browser window where you started the HTTP Request Log
Utility Start Page. Click View single client results to view the results from your
testing session. Click View all client’s results to view the results from all
sessions recorded.
5. Copy the resources from the resulting list and paste them into the following
file:
Tip
• The search results are only as accurate and complete as the testing you do.
• If the HTTP Request Log Utility Start Page was not accessed before the testing,
the entire log file is searched. Otherwise, the search begins from the point in
the log that immediately follows your most recent access.
• The types of resource files that are searched for can be configured. By default,
the defined extensions are .class, .ser, and .properties. To change from the
default, edit the fileExtensions variable in wtcore/jsp/wt/sysadm/
HttpRequestLogUtilStop.jsp file.
Note
Depending on the servlet engine configuration you may have to restart the
servlet engine for these changes to take effect.
• To find all resources needed for an applet, remove the client JARs used by the
applet and use the previous steps to log all resources that are used. This type of
testing creates a lot of network traffic since every resource is downloaded
from the server. You would typically only do this type of testing if you
believed the client JARs contained significantly more resources than were
required for your use cases. This generally should not be done with PTC
supplied *FCS.jar and *DSU.jar files.
For example, for a new logical JAR, foo, one would execute:
ant -f MakeJar.xml makeNewJarDescr -DlogicalJarName=foo
• This creates an empty FCS .includes files for the specified logical JAR in
codebase/jarContents, e.g. for a logical JAR, foo, this file would be
fooFCS.includes.
• This also creates head, Customization, DSU, and FCS .manifest files in
codebase/jarManifests for the specified logical JAR, e.g. for a logical JAR,
foo, these files would be foo.manifest, fooCust.manifest, fooDSU.
manifest, and fooFCS.manifest. All of these files except the head manifest
(e.g. foo.manifest) are initially empty. The head manifest defaults to have a
Class-Path entry listing the Customization, DSU, and FCS JAR
This entry should be amended if your logical JAR does not depend on
wtApplet.jar or has additional dependencies - in either case these should be
listed after the FCS JAR entry.
2. Create a .set file in <Windchill>/codebase/jarManifests that includes the
logical name of your new JAR.
3. Build your JAR by executing an appropriate target on the MakeJar.xml script
(from the codebase directory), e.g.:
ant -f MakeJar.xml buildFullClientJars -DlogicalJarNames=foo
Caution
When you create a new package, you need to add it to the
includeClassStartsWith property in wt.properties. This property lists the
package hierarchies that are included when resolving inherited descriptor
information. For example, if you add the package com.mycompany, use
xconfmanager to add “com.mycompany.” to the property, with the following
command from a windchill shell:
xconfmanager --add com.ptc.core.meta.descriptor.server.impl.
includeClassStartsWith=com. mycompany. -p
Make sure the package name ends with the period (".") character.
Note
When you are updating files for a maintenance release, remember to copy any
updated new packages and files that are used in your runtime system from
your test system to your production system.
Modeling Recommendations
Sites that use custom modeled classes using Windchill InformationModeler and
Java Annotations, may store their new packages and classes under the <Windchill
>/src directory structure; however, the packages that are defined should not be
stored under the <Windchill>/src/wt or <Windchill>/src/com/ptc directory.
Typically, newly developed packages and classes are stored under the domain
name of your company, as described previously.
Some customizations can also be stored under the <Windchill>/src/com/
myCompany directory.
You should create a new declarative XCONF file, for example, codebase/ext/
sitepart/sitepart.xconf. It would look like the following:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Configuration SYSTEM "xconf.dtd">
<Configuration targetFile="codebase/wt.properties">
<!-- Ensure that the file ext/sitepart/sitepart.properties is
appended to the list of custom property files.
-->
<Property default="ext/sitepart/sitepart.properties" name="wt.services
applicationcontext.WTServiceProviderFromProperties.customPropertyFiles"/>
</Configuration>
The Property statement (formatted on two lines for this guide) is one line in the
file that declares that the file ext/sitepart/sitepart.properties (a path relative to the
codebase directory) should be added as a value for the property:
wt.services.applicationcontext.WTServiceProviderFromProperties.customProp
ertyFiles
After running the above command, the wt.properties file is updated to reference
your service provider file, codebase/ext/sitepart/sitepart.properties.
Note
Be careful when adding sensors as they can have an impact on performance.
Consequently, you should ensure that you have performance measures that
you can reliably use to verify performance before and after adding sensors.
Additionally, validate all changes made to the System Monitor System Profile
against your development environment before deploying the changes into your
production environment.
For more information about the System Monitor, see the videos and
documentation available from http://www.ptc.com/go/psm.
Sample Code
The following code pattern should be followed when setting Administrator:
SessionContext previous = SessionContext.newSessionContext();
try {
SessionHelper.manager.setAdministrator();
// make calls to Queue Service
}
finally {
SessionContext.setContext(previous);
}
The following code pattern should be followed when bypassing access control:
boolean previous = SessionServerHelper.manager.setAccessEnforce
(false);
try {
// make calls to Queue Service
}
finally {
SessionServerHelper.manager.setAccessEnforce(previous);
}
• RollingFile appender
• IncomingRmiStatsAppender appender
• Filter configuration
Log4j 1.2 Usage Log4j 2.0 Usage
log4j.appender.IncomingR appender.IncomingRmiStats.filter.
miStats.threshold=WARN threshold.type=ThresholdFilter
appender.IncomingRmiStats.filter.
threshold.level=WARN
• Logger configuration
Log4j 1.2 Usage Log4j 2.0 Usage
log4j 1.2 usage for enabling Log4j 2.0usage for enabling loggers:
loggers: logger.WCUpgrade.name=
log4j.logger.com.ptc.wind com.ptc.windchill.upgrade
chill.upgrade=WARN logger.WCUpgrade.level=WARN
where, WCUpgrade can be any unique
name.
Log4j 1.2 usage for appending Log4j 2.0 usage for appending multiple
multiple appenders appenders
# Limit # Limit com.infoengine.log* loggers
com.infoengine.log* to outputting to
loggers to outputting to methodServerLogFile and
methodServerLogFile and MiscLogEvents
MiscLogEvents #Make sure to change the package
log4j.logger.com.infoengi structure as per your application
ne.log=, logger.infoengineLog.name=
methodServerLogFile, com.infoengine.log
MiscLogEvents logger.infoengineLog.additivity=
log4j.additivity.com.in false
foengine.log=false logger.infoengineLog.appenderRef.me
thodServerLogFile.ref=
methodServerLogFile
logger.infoengineLog.appenderRef.Mi
scLogEvents.ref=MiscLogEvents
Then from the new window that opens, you can enter the xconfmanager
command, as described in the next section.
The brackets ({}) in the syntax indicate optional parameters and indicate
parameters that you specify together. The syntax includes only the short version of
each parameter name. Parameter names are case-sensitive; enter the names using
the case shown in the syntax and the following table.
The following variables are used in the syntax of multiple parameters:
• <property_pair> is a command-line escaped name=value pair that is
compatible with the specification for java.util.Properties. For an example, see
Setting Property Values and Propagating Your Changes on page 157.
• <property_names> is a comma-separated list of property names.
• <property_file> is the relative or full path name of the property file.
• <declarative_xconf> is either a full URL or relative file path to the declarative
XCONF file.
In the following table, all parameter names are listed in alphabetical order with
corresponding parameter descriptions:
Parameter Name Description
--add Add the specified value at the end of the set of ordered
values already defined in the property. Use this
parameter only when the property is declared as a
multi-valued property.
To determine if property is multi-valued, you can
display the current set of values using the -d parameter.
The output from this parameter lists the multivalue
separator when the property is multi-valued.
-d Lists the values that are currently set and the
corresponding XCONF file where each value is set for
or
the specified properties.
--describe
This parameter executes after all parameter setting
options and the -p option have executed.
Note
The xconfmanager executes the following parameters in the order that they are
specified in the command:
-s, --reset, --add, --remove, --undefine
This means that if the same property is set in multiple parameters, the last
setting is used.
On a UNIX system, you can use doubles quotes or you can escape the space
character with a backslash. For example, use the following:
-s wt.inf.container.SiteOrganization.name="ACME\ Corporation"
On UNIX, dollar signs are usually interpreted by shells as variable prefixes. To set
a property value that has a dollar symbol in it, use single quotes around the
argument so that it is not interpreted by the shell or use backslash to escape the
dollar symbols. For example, use either of the following:
-s 'wt.homepage.jsp=$(wt.server.codebase)/wtcore/jsp/wt/portal/
index.jsp'
or
-s wt.homepage.jsp=\$(wt.server.codebase)/wtcore/jsp/wt/portal/
index.jsp
Other than escaping arguments so that the command line shell does not
misinterpret them, the values should not need to be escaped any further to be
compatible with XML or property file syntaxes. The xconfmanager escapes
property names and values automatically if necessary.
The following xconfmanager command used on a Windows system sets the wt.
properties property file wt.temp property to the WCtemp directory that is under
the Windchill installation directory [as defined by $(wt.home)]:
xconfmanager -s wt.temp=$(wt.home)/WCtemp -t wt.properties -p
Assuming that the command was executed from the Windows C:\ptc\
Windchill\bin directory, then the resulting output is:
Default product root=C:\ptc\Windchill\bin\..
java -jar
"C:\ptc\Windchill\bin\..\codebase\WEB-INF\lib\install.jar"
-r "C:\ptc\Windchill\bin\.." --reset wt.temp -p
Assuming that the command was executed from the Windows C:\ptc\
Windchill\bin directory, then the resulting output is:
Default product root=C:\ptc\Windchill\bin\..
java -jar
"C:\ptc\Windchill\bin\..\codebase\WEB-INF\lib\install.jar"
Tip
The previous example commands do not include the target file (in the -t
parameter). The target file is not needed when the property is known to be in
only one existing property file.
On a UNIX system, you can use doubles quotes or you can escape the space
character with \. For example, use either of the the following:
-s "wt.inf.container.SiteOrganization.name=ACME Corporation"
-s wt.inf.container.SiteOrganization.name=ACME\ Corporation
• In many UNIX shells, the use of a backward slash (\) escapes the following
character as a literal. In most cases, using forward slashes (/) in file paths is a
simple way to specify a path without having to know the intricacies of your
shell’s command line escaping rules.
• On UNIX, dollar signs are usually interpreted by shells as variable prefixes.
To set a property value that has a dollar symbol in it, use single quotes around
the argument so that the shell does not interpreted it or use backslash to escape
the dollar symbols. For example, use either of the following:
-s 'wt.homepage.jsp=$(wt.server.codebase)/wtcore/jsp/wt/portal/
index.jsp'
or
-s wt.homepage.jsp=
‘\$(wt.server.codebase)/wtcore/jsp/wt/portal/index.jsp
Other than escaping arguments so that the command-line shell does not
misinterpret them, you should not need to escape other values to be
compatible with XML or property file syntaxes. The xconfmanager escapes
property names and values automatically if necessary.
You can display the help for the windchill command by executing windchill with
the -h argument or with no argument.
The following tables list some of the arguments and actions applicable to the
windchill command. To see a complete list of the arguments, use the report
generated from the help (argument).
windchill Arguments
Arguments Description
(optional)
-h, –help Displays help and exits.
-v, –[no]verbose Explains what is being done when a command is
executed. Default is:
-- noverbose
-w, –wthome=DIR Sets the Windchill home directory. Default is the
parent directory containing the windchill script.
Note
On UNIX systems where you have multiple
instances of Windchill installed under the same
user account, settings made to WT_HOME and
SQLPATH environment variables by using this -w
option are overridden by any settings to these same
variables in the user's .cshrc, .login, and .profile
shell initialization files.
–java=JAVA_EXE The Java executable. Default is the wt.java.cmd
variable value specified in the $WT_HOME/
codebase/wt.properties file.
-cp, Java classpath. Default is the wt.java.classpath variable
–classpath=PATH value specified in the $WT_HOME/codebase/
wt.properties file.
–javaargs= Java command line arguments.
JAVAARGS
windchill Actions
Action Description
shell Sets up a Windchill environment in a new instance of
the currently running shell.
start Starts the Windchill server.
stop Stops the Windchill server.
status Retrieves the status of the Windchill server.
version Displays the Windchill installation version.
Windchill Shell
The windchill shell brings up a new command shell, from the parent shell that is
setup for the Windchill environment. This includes setting all environment
variables defined in wt.env property in the wt.properties file.
To execute the windchill shell, at the command prompt enter the following
command:
windchill shell
When you are finished using the windchill shell, you can exit the shell and return
to the parent shell.
PTC recommends running all server-side Windchill applications, tools, and
utilities from the windchill shell. Also, you can use the windchill shell to set up
your development environment to use javac or Java directly.
This tutorial is intended for programmers who are not that familiar with
Windchill.
167
Tutorial Overview
This tutorial illustrates a minimal configuration to create an environment in which
you can create administrative objects (users) and business objects (attribute
definitions, types and subclasses) and test them as an end user (by creating a
container and document instances). This will give you some idea how to work in
Windchill products, and help you ensure that your customization environment is
configured correctly.
Note
This tutorial is intended for programmers that are not familiar with Windchill.
Note
For any other organization you would not need to select Administrators.
But because this is the default site organization, the organization
administrator must also be a site administrator in order to manage types
and attributes.
17. Now you must declare the Organization Administrator user as an Organization
Administrator. Open the Navigator.
23. In the Add Organization Administrators dialog select Search, leaving the
search fields blank. Select the user you created to be the Organization
Administrator, and then select Add>> and OK.
25. Select “Library Creators” from the Creators pull down menu
27. In the “Add User to the Creators Group” dialog, select Search. Select the End
User and select Add>>. Then select OK.
28. You should now see your user in the Creators table:
6. Now you will see the details for your new library.
10. Here is the new document in its folder. Note that the Number is automatically
assigned.
11. Select the View Information icon to see details about the document.
2. The Upgrade Schema window will automatically appear, and disappear, after
executing:
Note
If the server is SOX configured then you have to first de-configure the
SOX and run the Add column command and again configure the server to
SOX.
6. With the Attributes tab selected, you can now select the “Create a new
attribute” icon and a new dialog will appear:
10. Type and Attribute Management will now show your Attribute:
11. Set the Default Value for the Size A attribute to “1”, select Save:
2. Navigate to the Details for the new document. Here you should see the Size A
attribute with value 101:
5. Follow the instructions above that you used to create the “Size A” local
attribute, to create a new local attribute, for your new type, called “Size B”
with a default value of “2”.
6. Edit your type and change the Icon for your type to “netmarkets/images/
repair_failure.gif”. The name of the icon is not meaningful, but it is a
distinctive image that you will be able to pick out in the UI later. Note that the
image automatically to the right of the path you just entered:
2. The new class will be in the package called com.acme. Change directory to
com/acme, creating the directories if necessary.
import wt.doc.WTDocument;
import wt.util.WTException;
import com.ptc.windchill.annotations.metadata.*;
@GenAsPersistable(superClass=WTDocument.class,
properties={
@GeneratedProperty(name="sizeC",
type=Integer.class, initialValue="3",
javaDoc="Integer value to represent the size of C.")},
iconProperties=@IconProperties(standardIcon="netmarkets/
images/stop.gif",
openIcon="netmarkets/images/stop.gif")
)
public class AcmeModeledDoc extends _AcmeModeledDoc {
The name of the icon is not meaningful, but it is a distinctive image that you
will be able to pick out in the UI later.
4. Now go back to the command prompt and compile your file with this
command: tools class -Dclass.includes=com\acme\*
13. We must now change the display name for the sizeC attribute and add it to a
group in each layout. Edit your type, and change the default name of the sizeC
attribute to “Size C”. Select Save
2. Review the Modeled Object info page for the new modeled subclass.
Note
The instances of the types you created are shown with the custom icons you
specified. This confirms that your new custom types are integrated with
standard Windchill functionality.
<Property>
<LogicalForm>defaultTraceCode</LogicalForm>
<ExternalForm>MBA|masterReference^WCTYPE|ext.ts.part.TSPartMaster~MBA|
defaultTraceCode</ExternalForm>
</Property>
...
</Class>
219
Customizing Role-based Visibility ............................................................................. 509
User Interface Stickiness ......................................................................................... 522
Defining Menus ....................................................................................................... 523
Adding Custom Content to the Home Page ............................................................... 539
Acquiring Data via Info*Engine ................................................................................. 544
NmObject Utilities.................................................................................................... 550
File Download ......................................................................................................... 556
Dynamically Resolved Attributes for Customizations .................................................. 563
Constructing and Rendering a Table Using the JSP Framework .................................. 564
Windchill Client Architecture Tree ............................................................................. 599
Attribute Customization............................................................................................ 615
Adding Custom Modeled Attributes to all Table Views................................................. 688
Attribute Tables ....................................................................................................... 689
Icon Delegates ........................................................................................................ 693
Creating Custom Graphical Representations ............................................................. 700
UI Validation............................................................................................................ 723
URL Authorization ................................................................................................... 773
Customizing the Find Number Field .......................................................................... 777
Inline Messaging ..................................................................................................... 784
Linking to Help Topics .............................................................................................. 788
Windchill Client Architecture Wizard.......................................................................... 791
Wizard Processing .................................................................................................. 819
Building Wizards to Create a Single Object................................................................ 844
Building Wizards to Edit a Single Object .................................................................... 866
Customizing Reusable Wizard Steps ........................................................................ 879
Handling External Requests Using an MVC Controller................................................ 919
Client Generated Form Data .................................................................................... 923
Customizing Information Page Components .............................................................. 931
Solution .................................................................................................................. 933
Customization Points ............................................................................................... 938
Sample Code .......................................................................................................... 954
Updating Legacy information Pages.......................................................................... 957
Configuring Pickers ................................................................................................. 962
Configuring a Context Picker .................................................................................... 972
Configuring an Item Picker ....................................................................................... 982
Configuring an Organization Picker........................................................................... 990
Configuring a Type Picker ........................................................................................ 999
Configuring a User Picker ...................................................................................... 1017
Configuring a Participant Picker in JCA ................................................................... 1024
Configuring a Participant Picker in AngularJS .......................................................... 1036
Configurable Link Tables........................................................................................ 1044
Collecting Configurable Links ................................................................................. 1058
Configurable Revision Links ................................................................................... 1070
Customizing Indexing Behavior .............................................................................. 1074
Customizing Solr ................................................................................................... 1076
Customizing Faceted Search ................................................................................. 1081
Enabling Text Preview Column for Additional Objects............................................... 1083
This chapter explains and gives some basic overview of the Windchill Client
Architecture UI Framework.
Before reading this chapter, you should be familiar with Java, JavaServer Pages
(JSP), JavaServer Pages Standard Tag Library (JSTL) and Expression Language
(EL).
Note
Before reading this chapter, you should be familiar with Java, JavaServer
Pages (JSP), JavaScript, JavaServer Pages Standard Tag Library (JSTL) and
Expression Language (EL).
• For more information on JSTL see: http://java.sun.com/products/jsp/jstl/
• For more information on EL see: http://java.sun.com/j2ee/1.4/docs/
tutorial/doc/JSPIntro7.html.
The Windchill Client Architecture provides a framework for building pages easily
and consistently by providing a standard set of components and services that are
configurable and customizable. The set of components includes, but is not limited
to, a table, a tree, an information page, a wizard, and a dynamic javascript menu.
At a lower level, these container components use other common components,
called actions, action models and GUI components, to display data inside of them.
URL Strategy
In a Windchill client application starting at 10.0 the URL consists of multiple
pieces. The URL still begins with the host information and the Windchill web app
name. Then the URL has the following components.
app/ app/ is the address of the shell. The shell renders the header,
navigator and a blank content area.
# The # character is the token. The complete 10.0 URL is actually
made up of two URLs put together. This token marks the end of
the URL for the shell and the beginning of the URL for the
content that will be displayed within the content area.
The URL after the # token can also take the formptc1/
<objecttype>/<action name>, which mirrors the action
mappings in actions.xml, for example: ptc1/report/
listUpdates
Query Strings After the question mark is the query-string as in any other URL.
It is possible to have two query strings in the URL. When the ?
is before the # token the query string parameters will be passed
to the shell. When the query string is after the content address
after the # token the parameters will be passed to the page in the
content area.
Most pages need to be loaded through the shell to work correctly. Calling their
URL’s directly will load them without the CSS and JavaScript they need to
function correctly. Every page in Windchill is now being served through a
controller class. Even URLs which look like direct JSPs are being served through
the LegacyController. Spring MVC is used under the covers to configure them.
SeeMVC Components on page 247 for more information.
Java Builders
This approach presents several advantages over the older JSP and Tags based
approach. By separating the model and controller from the JSP, we enable a more
flexible and maintainable system. For example, several different JSPs can now
take advantage of the same java builder. And, because, builders are now written in
java, they can share attributes through inheritance. The basic steps to produce
many components (table, tree, attribute panel, etc) are:
• Describe the component (Component Config Builder)
• Acquire the necessary data (Component Data Builder)
• Render the component (JSP)
table.setLabel("My Table");
table.setSelectable(true);
table.setType("wt.pdmlink.PDMLinkProduct");
table.setActionModel("my_toolbar_actions");
table.setShowCustomViewLink(true);
table.addComponent(factory.newColumnConfig(ICON, true));
table.addComponent(factory.newColumnConfig(NAME, true);
table.addComponent(factory.newColumnConfig(INFO_ACTION,
false));
return table;
}
• ComponentDataBuilder
The data for your UI is created by a Java Class that implements the
ComponentDataBuilder Interface. This interface contains one method
buildComponentData. The object returned from this method should
represent the Model for the UI and can take multiple forms. Some examples of
what this method might return are ComponentData, a Persistable, a
QuerySpec, any custom Java Object, etc. One example of a
ComponentDataBuilder might look like the following:
View — JSP
In this approach, the JSP is simply a “view”, rather than a combination of all
three, as it is in the JSP and Tags approach. Each component has a default view
(JSP) to render out the component, however if you wish to override the default
view you can call the setView() on the ComponentConfig that your
ComponentConfigBuilder returns. All the view jsps should be located in
codebase\WEB-INF\jsp base location.
• Basic Elements of the JSP
When Creating a JSP view for a Java Builder, you will need to be aware of a
few important jsp fragment files. The first and most important is the begin_
comp.jspf. This files exists in codebase/netmarkets/jsp/util/.
The purpose of this jspf is to setup the model data information required by the
view.
Another jspf that is included is the end_comp.jspf also located in
codebase/netmarkets/jsp/util/. The purpose of this file is to:
Mark that the page load is complete to allow proper functioning of the
javascript within the page. An example of a jsp view might look like:
<%@ taglib uri="http://www.ptc.com/windchill/taglib/jcaMvc" prefix=
"mvc"%>
<%@include file="/netmarkets/jsp/util/begin_comp.jspf"%>
<mvc:table setPageTitle="true"/>
<%@ include file="/netmarkets/jsp/util/end_comp.jspf"%>
Supported Components
• Table
Controller — JSP
• Basic Elements of the JSP
You will need to be aware of a few important jsp fragment files. The first and
most important is the begin.jspf. This files exists in codebase/
netmarkets/jsp/util/. The purpose of this jspf is to:
○ Include a tag for rendering the shell that surrounds all pages.
○ Take care of housekeeping like:
◆ Instantiates the beans (context, clipboard, etc)
◆ Executes a command (for actions only)
◆ Includes some JS functions
◆ Creates ONE form for the page data (called mainform)
Supported Components
• Wizard (Create/Edit)
• Table
• Tree
• Property Panel
• Attribute Table
Additional Resources
• Tag Library Documentation
The Windchill Tag Library Documentation is delivered with the product and
can be accessed through the UI. To locate the documentation, first enable the
Data Utilities
Data Utilities are delegates invoked during construction of the model that allow
post-processing and/or augmentation of the data returned by data acquisition
APIs. For more information on GUI Components see Attribute Customization on
page 615.
Action Service
Configuration of actions and action models that are available within the system
are defined using xml files. There is an action service that reads these xml files
and manages the set of actions and action models. Interaction with the service is
done via the components. Developers in general would not call the service
directly. For more detailed information about the action framework see Adding
Actions and Hooking Them Up in the UI on page 473.
Validation Service
Validation of actions and properties can be done via logic encapsulated into a
validator that gets executed when a component such as a action menu, table, or
property panel includes that action or property. When a page including one of
these components is requested, the framework will call the validation service to
determine which of the actions or properties should be displayed, disabled, or
hidden. The service will invoke the appropriate delegates to gather the requested
Additional Resources
Theme
The Windchill theme defines the look and feel (colors, fonts, images etc). These
are controlled by css. For more information on adding custom css see Adding
Custom Code to all Windchill Client Architecture Pages on page 245 for more
detailed information.
Javadoc
The Windchill Javadoc is delivered with the product and can be accessed through
the UI. To locate the documentation, first enable the customization examples and
tools, then browse to the customization navigation and select the tools option. For
more information see Customization Tools Overview on page 381.
Under the API documentation section of the page you will find a link to the
Windchill Javadoc.
Java Beans
There is a set of Java Beans that is part of the framework that carries data like
context and session information. The developer does not need to interact with
most of the beans. See Windchill Client Architecture Common Objects Overview
on page 236 for more information.
NmCommandBean
NmCommandBean provides Windchill Client Architecture state information to
other Windchill Client Architecture layers. It is the what, where, and how of the
UI. It wraps the request object and adds value by parsing the parameters into
related items.
Once initialized by the request, the NmCommandbean can answer Windchill
Client Architecture related questions. It essentially carries the request and helper
methods to access the jca state information.
Interesting attributes:
• Context: the where compcontext, parentContext, element
context, etc are used to determine what page is displayed and where actions
are launched. (Note that this is becoming obsolete and should be deprecated in
the next release.)
• oids : the objects that actions or pages apply to.
Contains a number of helper APIs:
• getActionOid() : gets the object that is the target of the action.
• getPageOid(): gets object that the page is being displayed in this page.
• getViewingContainer() : gets the container that the page is displayed
in.
See the javadoc for more info api usages.
NmAction
NmAction represents a line from actions.xml which describes a page in
Windchill. It is rendered as all the icons and links that one can click to make
changes to the Windchill system. Each jsp page should be described by an
NmAction in an xml file. The localized attributes of the NmAction can be
found in the action.properties or other rbInfo files.
NmSimpleOid
NmSimpleOid represents a non-persisted business object. It is often to represent
some item that has not been created yet or some object that wraps a persistable
with more information. String parsing of the NmSimpleOid is completely
handled by the code for the relevant table and actions and should be in an
NmObjectUtility. See NmObject Utilities on page 550 for more information.
NmContext
NmContext represents a UI address of a page. (Note that this is becoming
obsolete and should be deprecated in the next release.)
• Component is a jsp page
• Jsp page can include multiple components
• Component address includes addresses of ancestor components
• Context (address) of a component B is “Address 1 - Address B”
Note
More Windchill Javascript API information is available directly in the
Windchill UI. For more information, see Customization Tools Overview on
page 381.
TableUtils — package
Name Purpose
getTableRows (parentNode) Return array of Nmcontexts for each
row in a table given the outer DIV
DOM node.
getTableRowsByID (tableID Return array of Nmcontexts for each
row in a table given a table id
getTreeRows (parentNode) Return array of Nmcontexts for each
row in a table given the outer DIV
DOM node.
findTableID (node) Given some DOM Element, walk up
the DOM tree to figure out which table
this is in.
findParentTableNodeId (node) Given some DOM Element, walk up
the DOM tree to find the table DOM
Node.
getAddedRows (tableid) Gets the hidden input field that contains
the added rows of a table id. Returns
String that can be tokenized.
getRemovedRows (tableid) Gets the hidden input field that contains
the removed rows of a table id. Returns
String that can be tokenized
getParentTR (node) Walk up the Dom tree finding the first
<tr> tag
removeParentRow (oid, node, tableid) Remove a row from a table/tree
isTableCheckBox (node) returns true/false if the dom NODE is a
asyncResponseHandler
Name Purpose
handleResponse (responseText, Parses actions from an asynchronous
responseObject) response. Generic high level method
that will delegate to all the types of
responses.
stripText (text, Gets rid of unwanted text from the
divID, response. Substrings out antying not
inbetween the html comment.
skipScriptEval,
Can execute javascript blocks
start, conditionally.
end) Start/end are the html comment strings
to use to find the response in.
requestHandler
Name Purpose
handleRequest (table_id, params) Refreshes a table given the params
doRequest (url, options) Make the ajax request for the table.
Used by the above method to change
the url with the options set.
Wizard.js functions
Name Purpose
handleRequest (table_id, Refreshes a table given the params
params)
doRequest (url, options) Make the ajax request for the table.
Used by the above method to change
the url with the options set.
parseAnonymousParams (startIndex, Add request params to the options
params, result) based on the params list passed in.
getParamString Adds all this form params to the ajax
request including the params passed in.
updateStepImage Updates the wizard step indicator
images for all steps based on the
current state.
updateEmbeddedText Updates the embedded help based on
the current step.
getNextStep Gets the next step id.
setNextStepDirty Sets the next step in the wizard to be
refreshed when displayed.
goBack Make the wizard go back one step
goNext Make the wizard go to the next step
setActiveStep (stepId, wizardAction) Makes a specific step active.
wizardAction is an optional parameter.
It indicates if the user is attempting to
go back or forward in the wizard.
findStepIndex Find the index of a step id
setNextStep Override what the next step id is
setStepDirty Set a step to need a refresh should it
Javascript files
To add any custom javascript to all the pages, you should create a new custom
jsfrag file. The file needs to be deployed in: codebase\netmarkets\
javascript\util\jsfrags
The file can be named custom.jsfrag or any other name that is not already in
use.
To include the file in all pages run the combine command. This will make the js
available in main.js: Windchill/bin>ant -f jsfrag_combine.xml
CSS Files
To add any custom css scripts to all the pages, modify the
netmarkets.presentation.cssFiles property in site.xconf to
have the necessary css files included. You can include multiple css files as a
comma or semicolon separated list in the value. Note that order is important, and
that the files will be loaded after the Windchill style sheets so they will properly
override the default styles.
<Property name=" netmarkets.presentation.cssFiles"
overridable="true"
targetFile="codebase/presentation.properties"
value="mypath/mycss.css;mypath/mycss2.css"/>
Maintenance Messaging
The file codebase/netmarkets/jsp/util/begin_custom.jspf can
also be used to add custom messages to the page for system maintenance or mass
communication. For example, place the following code in this file:
<div style="color: sienna; position: absolute; top: 15px; z-index: 1000;
left: 300px; font-size: 18px;">
<h1>This is a test</h1></div>
You should place any HTML for your message within a div as in this example.
You can then use css to position and style the message as desired.
{
color: #53bc3c;
}
3. Create a custom css for the reference designator differences minus values. The
following example will display the values as red:
span.dsb-reference-designator-diffs-minus-value
{
color: #FF0000;
}
Customization Points
codebase/netmarkets/jsp/util/begin_custom.jspf
247
MVC Components Overview
This explains and introduces the different pieces of the Windchill Client
Architecture UI Framework.
• MVC on page 248
• Data Sources on page 258
• JCA Components on page 267
MVC
Model–View–Controller (MVC) is a software architecture, currently considered
an architectural pattern used in software engineering. Model represents enterprise
data and the business rules that govern access to and updates of this data.
View renders the model. Controller translates interactions with the view into
actions to be performed by the model.
For web-based clients such as browsers uses Java Server Pages (JSP ) to render
the view, Servlet as the controller, and Enterprise JavaBeans (EJB ) components as
the model.
MVC in Windchill
In Windchill 9.x, for JCA Clients, JSP was serving both as the Controller and
View. In Windchill 10.0, we are introducing a clear separation between Controller
and View for which we are using Spring MVC Framework.
The primary motivation for this move is to enable our components to be both
requested by and rendered to any client technologies. The MVC pattern is a well
understood industry standard approach that allows us to better leverage 3rd-party
technologies and training. Finally, the MVC pattern improves the maintainability
and testability of our implementations.
Having multiple servlets as controllers is going to be difficult to manage and
hence we have adopted the Front Controller pattern approach – a main servlet to
make the control more manageable. DispatcherServlet acts as the Front controller.
Request Handling
The servlet and servlet mapping for the Web container is defined in
<Windchill>\codebase\WEB-INF\web.xml. The below mentioned url
patterns are mapped to Spring DispatcherServlet and hence will be termed as
MVC requests.
<servlet-mapping>
<servlet-name>MVCDispatcher</servlet-name>
<url-pattern>/servlet/WizardServlet/*</url-pattern>
<url-pattern>/servlet/ActionsMenu/*</url-pattern>
<url-pattern>/servlet/RecentList/*</url-pattern>
<servlet>
<description>MVC Dispatcher Servlet for JCA</description>
<servlet-name>MVCDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.
DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
The web container, based on the servlet mapping configured, directs all the MVC
Requests to Spring DispatcherServlet.
Application Context
An application Context represents the set of configuration files that are used to
provide configuration information to the application and is in <Windchill>\
codebase\WEB-INF\MVCDispatcher-servlet.xml.
• Imports all the Spring configuration xml files that reside at <Windchill>\
codebase\config\mvc\ folder. Any custom configurations should go in
<Windchill>\codebase\config\mvc\custom.xml.
Note
All Spring classes with @Controller annotation must have a URL-mapping
with @RequestMapping in the same class. Other request mapping
configurations of such classes, whether available in application context XML
or properties file, are not supported from Spring 5.0 and Windchill 11.1 M020.
When the web container is initialized, Spring loads the application context and
hence to get effect of any configuration changes, you need to restart the server.
MVC Components
The components that extend/implement ComponentConfig interface are MVC
components. Some of them are :
• TableConfig
• AttributesTableConfig
• TreeConfig
• AttributePanelConfig
• InfoConfig
• ColumnConfig
• PropertyConfig
• PropertyPanelConfig
Note that framework will throw an error if two builders will have the same
component id. Spring initialization will fail in the MethodServer start up
phase. If you need to override an OOTB builder, please use
OverrideComponentBuilder annotation.
@ComponentBuilder(value="{compId1, compId2, compId3}")
public class OOTBBuilder1 extends …… {
}
@OverrideComponentBuilder
public class MyCustomBuilder1 extends …… {
}
TypeBased
To build certain components, you may need the Windchill Type of the context
object playing a role in finding the appropriate builder. For example you have an
info page and you want to populate the content based on the Windchill Type. For
these scenarios, we have introduced an annotation “TypeBased” that can be
used in the builder, to attach the builder to a specific Windchill Type. This works
with ComponentBuilder.
@ComponentBuilder("compIdA")
@TypeBased(value="{WTPart, WTDocument}")
public class OOTBBuilder1 extends ……{
}
@ComponentBuilder("compIdA")
@TypeBased(“myPart”)
public class OOTBBuilder2 extends ……{
}
The builder-scan implementation scans the entire classpath, so you should take
care to be specific with the package name you declare if using scanning. (don’t
scan com.ptc.* for example). In addition, this means that classes that are
outside your interest, but that are in the classpath and match the package
hierarchy, will also get scanned. From a performance standpoint
(MethodServer startup) each scan adds up time. You are requested to take
advantage of the OOTB scan provided on “com.ptc.mvc.builders” base
package. This means that all the builders that you author should be under com.
ptc.mvc.builders package. If you are not using the OOTB scan, the rule of
thumb is to use the scan if there are more than 10 builders available in the
package.
2. Explicit configuration : To do this, simply add a bean declaration for the
builder to the <Windchill>\codebase\config\mvc\custom.xml
e.g <bean class=" my.builder.class.name "/>
You are encouraged not to specify the bean name while declaring the bean and
use @ComponentBuilder annotation in the builder for proper registration
of it in the Spring bean factory.
Use Case 2
Here the components need to be defined and they exist together. E.g. you want
property panel coming with a table.
• There is a need for ComponentDataBuilder.
• Infrastructure invokes the buildComponentData for each
ComponentConfig available in the MultiComponentConfig. It’s
invoked in the same order it has been put in the MultiComponentConfig.
• You can access the rawData for the ComponentConfig that has already
been processed from the ComponentParams supplying the componentId
• You need to specify a view jsp for this ComponentConfig as no default
view can handle that.
@ComponentBuilder("test.array.PQ")
@Override
public ComponentConfig buildComponentConfig(ComponentParams
params)
throws WTException {
MultiComponentConfig configs = new MultiComponentConfig();
configs.setView("/test/array.jsp");
return configs ;
}
@Override
public Object buildComponentData(ComponentConfig config,
ComponentParams params) throws WTException {
if ("component1".equals(config.getId())) {
//return data for table with id= component1
} else {
//return data for table with id= component2
}
}
}
Data Sources
It’s an infrastructure for holding the data and streaming the data to the client. It
will enable faster page loads as well as the potential for asynchronous server
processing of results. The basic strategy is to return large result sets to clients in
chunks, along with an ID that can be used to get more chunks. From the UI
perspective it looks like the data is streaming into the client. This approach is
different from DB paging, where we persist the big result set in the database. With
DataSources, the result lives in memory only for as long as it takes the client to
request it in chunks. In addition, there will be support for the server to add chunks
to the datasource in a separate thread, so one can request the datasource and spin
off a thread to work on getting data for it, without the client waiting.
MBean operations
Parameter Description
cancelLongRunningDataSources Cancel any datasources that have been
running for at least the given amount of
milliseconds, in all user sessions. This
will cancel both active and inactive
DataSources
MBean configuration
Parameter Description
AllEmptyPollingTimeout The timeout in milliseconds to wait for
data chunks when the client polls for
chunks and none of the ids it asked for
have chunks available
ChunkBlockingLimit Controls the number of chunks a
DataSource can hold before it blocks
the addition of more items until
something polls it or it times out. The
actual number of items this resolves to
is
ChunkBlockingLimit*MaxChunkSize.
DataSourceTaskPoolKeepAliveTime The amount of time in milliseconds to
keep idle threads alive in the
DataSource task pool
DataSourceTaskPoolSize The maximum number of threads
allowed in the DataSource task pool
DataSourceTimeout The amount of time in milliseconds to
keep idle DataSources alive
FeedbackBlockingLimit The number of feedback items a
DataSource can hold before it blocks
Performance concerns
• Threads Per Components
In addition to the MBean properties to adjust different sizes and timeouts, the
property numberOfThreadsPerComponent can have an effect on overall
performance of a component. This property is used to modify the maximum
number of threads allowed by any component to process data out of the
database through the Data Utilities. These threads process data of size of the
RawDataChunkSize MBean value and are short lived. Increasing the
number will not likely help further because the data coming from the database
JCA Components
These are few implementation of ComponentConfig :
• JcaTableConfig
• JcaAttributesTableConfig
• JcaTreeConfig
• JcaAttributePanelConfig
• JcaColumnConfig
• JcaInfoConfig
• JcaPropertyConfig
• JcaPropertyPanelConfig
ComponentConfigFactory
Builders which are ComponentConfigFactoryAware will be injected with
a ComponentConfigFactory. ComponentConfigFactory provides
instances of different implementations of ComponentConfig (eg table, tree
etc). In JCA, the injection happens in the bean post processor and is configured in
<Windchill>\codebase\config\mvc\jca-mvc.xml.
<bean class="com.ptc.mvc.components.support.
ComponentBuilderBeanPostProcessor">
.....
<property name="componentConfigFactory" ref=
"jcaComponentConfigFactory" />
<property name="infoComponentConfigFactory">
......
</property>
<property name="typedAttrLayOutFactory">
<bean class="com.ptc.jca.mvc.components.
JcaTypedAttrLayOutFactory" />
</property>
</bean>
<bean name="jcaComponentConfigFactory"
class="com.ptc.jca.mvc.components.JcaComponentConfigFactory"
factory-method="getInstance" />
ComponentDataConvertor
<bean id="jcaComponentDataConverter"
class="com.ptc.jca.mvc.components.
JcaComponentDataConverter" />
<bean id="jcaComponentDataBuilder"
class="com.ptc.jca.mvc.components.
DefaultJcaComponentDataBuilder"
scope="prototype">
<property name="componentDataConverter"
ref="jcaComponentDataConverter" />
</bean>
<bean id="jcaComponentBuilderResolver“
class="com.ptc.jca.mvc.components.
JcaComponentBuilderResolver">
......
<lookup-method name="createJcaDataBuilder"
ComponentBuilder Resolver
• If the DataBuilder specified is an instance of
ConvertingComponentDataBuilder,
JcaComponentBuilderResolver uses that as the
ComponentDataBuilder.
• If the DataBuilder specified is an instance of ComponentDataBuilder,
JcaComponentBuilderResolver uses that as the internal builder for the
DefaultJcaComponentDataBuilder.
Action Handling
Actions can be broadly divided into three groups.
These actions can be performed once your objects are loaded.
• Group 1 – Actions which act only on loaded data
○ Row-level and multi-select actions
○ Select all, Ctrl/Shift select, Clear all
○ View selected objects only
• Group 2 – Actions which act on the entire data set
These actions can be performed anytime (If incomplete data set, goes to the
server to get all the data)
○ Switching table views
○ Search in table
○ Export list
• Group 3 – Actions which apply to the table itself
These actions can be performed anytime
Sorting
Sorting is a special action and with DataSource, depends on the data in the client.
• If complete data set
○ Sorting happen in the client
• If data still loading
○ Sorting happen on the data already in the client
○ Insert remaining polling rows into the client in sorted order
• If results limit was reached
○ Sorting happen in the client
○ Only the rows that are in the client are sorted (not the complete data set)
• Version column is an exception, which makes a server trip to do the sorting,
but only on the data set available in the client.
Tips
@RBEntry("Test Message")
public static final String TEST = "test";
If your builder extends OOTB abstract builders, take advantage of its api
AbstractComponentConfigBuilder.getMessageSource(String resourceBundle)
AbstractComponentDataBuilder.getMessageSource(String resourceBundle)
This chapter explains and gives some basic overview of the Windchill Client
Architecture UI Framework.
Before reading this chapter, you should be familiar with Java, JavaServer Pages
(JSP), JavaServer Pages Standard Tag Library (JSTL), and Expression Language
(EL).
Scenario 1
A UI component on your page executes an action. When the action completes,
you would like to update a portion of the launch page to reflect the results of an
action.
• Example: A user launches a wizard to create a new part from the folder
browser of a product. When the user clicks OK you send the form to the server
and create the part. After doing so, you would like to add a row to the folder
browser table that displays the part just created.
• Example: A user clicks a menu item in a product folder browser to delete a
document. The menu item action calls a command to delete the object from
the database. When the command completes, you would like to delete the row
for that object from the folder browser table.
• Solution: Use the partial page refresh capabilities built into the Windchill
action and form/command processing framework
Scenario 2
You would like to refresh an inline element of the page when some event occurs
• Example: You have a page that displays time values in a default time zone. It
also has a button that allows the user to change the time zone. When the user
changes the time zone, you want to redisplay the time values accordingly.
• Solution: Add an onChange event handler for the time zone button that calls
the requestHandler.doRequest() JavaScript function to recompute
the time display value.
Solution
Specify some Ajax based configuration and code in the action to allow the Ajax
refresh to work.
Solution Elements
Element Type Description
<your actions>.xml XML XML file that defines menu, toolbar,
wizard, and other actions in the
Windchill action framework
<your>formProcessor.java Java A processor that performs operations
based on user data submitted in a
wizard
<your wizard step>.jsp Jsp Jsp to partially refresh in a wizard
Note that rows can be added and removed from the table by switching the flag on
the refreshInfo to be NmCommandBean.DYNAMIC_ADD or DYNAMIC_
DELETE respectively.
In the example above, the jsp that is invoked calls a Java tag that writes a JSON
object to the response.
<req:getFolderAndContactByOidTag oidString="${param.oid}" />
Rather than define the onSuccess function inline, you can just specify the name
of a function to be called:
onSuccess: handleResponse,
In this example, the batched requests are sent to a servlet engine controller class
called “NumericController”. The individual requests provide information
about a number value that needs to be displayed on the page. The controller loops
through the individual requests, calls a Java class to create a localized display
value for the number, and returns a JSONArray of JSONObjects, each of which
contains a display value and a unique id corresponding to the id of a HTML div
tag on the page. The success callback function replaces the contents of the div tags
with the display values.
try {
String displayValue =
NumericFormat.formatValueForDisplay(type,
externalForm,
Boolean.valueOf(isPercent),
Boolean.valueOf(isCurrency));
response.setContentType("application/json; charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(result.toJSONString());
} catch (Exception e) {
log.error("Problem displaying and formatting
number in NumericController.", e);
}
Sample Code
Examples of usage in out-of-box code. Many examples exist, search
actions.xml files for ajax=”component” ajax=”row” or the processors
for calls to addDynamicrefreshInfo.
Scope/Applicability/Assumptions
This process should be applied when you want to create bread crumbs for one or
more Windchill pages that do not currently have bread crumbs or you want to
modify the bread crumbs displayed on a Windchill page.
Intended Outcome
Bread crumbs are displayed as desired.
Solution
Create and register a BreadCrumbDelegate Java class with an inner class that
extends AbstractBreadCrumbGenerator to display the bread crumbs.
Prerequisite Knowledge
To create the necessary bread crumb classes you will need an understanding of the
Java programming language.
Note
Since the factory creates only one static instance of each delegate, the delegate
class itself should not use class instance variables or be stateful in any way.
Sample Code
The following code is extracted from the
AssignmentsBreadCrumbDelegate which generates the bread crumbs for
an task (WorkItem) object.
public class AssignmentBreadCrumbDelegate implements
BreadCrumbDelegate {
@Override
@Override
public AbstractBreadCrumbGenerator getGenerator(Persistable
contextObject,
WTContainer container, String url) throws WTException
{
return new AssignmentCrumbGenerator(p, container);
}
/**
* IDs for Assignment list components.
*/
protected static final String PRODUCT_ASSIGNMENTS_LIST_ID =
"netmarkets.product.assignments.list";
protected static final String LIBRARY_ASSIGNMENTS_LIST_ID =
"netmarkets.library.assignments.list";
protected static final String QUALITY_ASSIGNMENTS_LIST_ID =
"com.ptc.qms.listAssignments";
protected static final String PROJECT_ASSIGNMENTS_LIST_ID =
"project.assignments";
/**
* Initialize as a generator and set instance variable
* container so that the Assignments crumb can be made.
* First tries to set container to c. Next
* tries to set container to contextObject's container (if
* contextObject is WTContained). Next tries to set
* container to contextObject's source object's container.
* Lastly tries to set container to contextObject's
* primary business object container.
*
* @param contextObject
* @param c
* @throws WTException
*/
if (sourceRef != null) {
Persistable source = sourceRef.getObject();
if (source instanceof WTContained) {
containedItem = (WTContained) source;
}
}
if (containedItem != null) {
@Override
public JSONArray getCrumbs() {
try {
addContainerCrumbs(container);
} catch (Exception e) {
log.error("Couldn't create the crumbs for
container "
+ container, e);
addCrumb(getSecuredInfoCrumb());
}
try {
addCrumb(createAssignmentsCrumb());
} catch (Exception e) {
log.error("Couldn't create the Assignments Table
crumb.", e);
addCrumb(getSecuredInfoCrumb());
}
return crumbs;
}
/**
* Makes the Assignments List crumb for a given assignment
object.
*
* @return JSONObject
* @throws WTException
* @throws JSONException
*/
protected JSONObject createAssignmentsCrumb() throws
JSONException,
WTException {
if (container == null) {
log.warn("The Assignments list crumb will not be
made because
container is null.");
return null;
}
return url;
}
}
}
Additional Resources
Related Package/Class Javadoc
• com.ptc.jca.mvc.controllers.BreadCrumbController
• com.ptc.windchill.enterprise.navigation.breadcrumb.
BreadCrumbDelegateFactory
• com.ptc.windchill.enterprise.navigation.breadcrumb.BreadCrumbDelegate
• com.ptc.windchill.enterprise.navigation.breadcrumb.
AbstractBreadCrumbGenerator
• com.ptc.windchill.enterprise.navigation.breadcrumb.
FolderedBreadCrumbDelegate
Packaged Samples
This section contains information on the sample code that is provided within the
system.
@Override
public AbstractBreadCrumbGenerator getGenerator(Persistable p,
WTContainer container, String url) throws WTException
{
return new FolderedCrumbGenerator(p, container);
}
protected Persistable p;
this.p = p;
}
@Override
public JSONArray getCrumbs() {
// Try to add the container crumbs.
try {
addContainerCrumbs(container);
} catch (Exception e) {
addCrumb(getSecuredInfoCrumb());
}
return crumbs;
}
…
When visiting the info page link for our example haiku, you can see the bread
crumb shows that this particular object resides under Site ▶ Folders. Note: only
users with adequate permissions will be able to view this object’s info page.
Location of Example
To navigate to this example in the product go to Customization ▶ Component
Catalog ▶ Bread Crumb ▶ Bread Crumb Component based on the Context Object.
Note
The Component Catalog is not enabled in the Windchill UI by default. For
instructions on enabling the Component Catalog, see Enable Customization
Utilities on page 381.
Location of Example
To navigate to this example in the product go to Customization ▶ Component
Catalog ▶ Bread Crumb ▶ Bread Crumb Component based on the URL.
Note
The Component Catalog is not enabled in the Windchill UI by default. For
instructions on enabling the Component Catalog, see Enable Customization
Utilities on page 381.
Scope/Applicability/Assumptions
This document assumes you are familiar with configuring Windchill information
pages, and configuring information page tab sets in particular.
Intended Outcome
Upon reading this best practice you should understand how information page tabs
can be created and configured by users and administrators. You should also be
able to utilize the customization points to customize how tabs are handled for
information pages.
Solution
Tabs created dynamically by users and administrators will be persisted in the
database.
Prerequisite Knowledge
To apply this process, you need to have an understanding of the following:
• Basic development involving Java, XML, and JavaScript particularly
JavaScript Object Notation (JSON)
• An understanding of how information page tabs are created and configured via
action models (See Customizing Information Page Components on page 931
for more information)
The tabs that a user sees an information page are thus a combination of the actions
defined by the actions model XML, any tabs created by the site administrator, any
tabs created by the organization administrator, and any tabs created by the user. It
is important to note that information tabs are linked to an object type. That is, if
“Tab A” is created for a document, then “Tab A” will be seen on every document
information page, but not on information pages for other object types (i.e. Part).
The default implementation of the TabSetDelegate follows the following
algorithm for determining what tabs to display for a given information page:
• Retrieve the tabs defined by the action model
• Retrieve the tabs defined by the site administrator for the object type
Customization Points
This section contains the following topics:
• Customizing Tabs via Windchill UI on page 302
• Customizing Tabs by Implementing Custom TabSetDelegate on page 309
• Customizing Tabs by Implementing Custom TabController on page 310
General Procedure
Users can create and configure a tab by visiting an information page for the type
you wish to configure. Click the tab with the “+” icon to create a new tab, and
configure the tab as needed.
It is important to note that throughout this process the tab is being saved, without
any explicit action required. The very act of creating a new tab creates a new tab
object in the database. Any actions to the tab, including changing its name, adding
content, or deleting it, are immediately saved on the server.
The general procedure for adding and configuring a tab for a specific type is
illustrated below. In this example, we will create and configure a tab that will
display history information for documents:
1. Visit the information page of any document, and create a new tab by clicking
the “+” tab:
3. You can than rename this tab to something more meaningful. In this case,
since this tab will be used to display history information, we will rename it to
“History” by right-clicking on the tab itself, and invoking the Rename Tab
action:
4. Enter the desired name into the resulting dialog, and you should see the tab’s
new name:
5. New tabs are initially added to the right most end of the tab set. You can move
your new tab to a different position in the tab set using a left-mouse click and
drag-and-drop:
Note
The order set for custom or configured tabs is not retained after an
upgrade.
6. At this point, we have created a tab, given it a descriptive name, and moved it
to the desired position in the tab set. We have yet to add any content to it,
however, so it is not very useful yet. We’ll add content to the tab by clicking
the “Customize” link. The Customize menu shows the content items that can
be added to the tab. Content items are typically tables or attribute panels. The
main Customize menu shows categories of content items. Each category has a
submenu showing the content items in that category. You can select all the
content items in a category by checking the box associated with the category
or you can select individual content items within a category. We’ll add the
“Version” table to our new tab by selecting it in the Customize menu:
8. You will get below confirmation dialog, by clicking OK, the tab will get
deleted and by clicking Cancel you will be returned to the page.
9. The tab can also be deleted by clicking “x” on the tab itself.
A public tab can be made private by invoking “Set Private” tab action. Making a
public tab private will remove the tab for all other users, this could be confusing to
the users.
A public tab can be made private by invoking “Set Private” tab action. Making a
public tab private will remove the tab for all the users of that organization; this
could be confusing to the users.
As stated earlier, administrators can only reorder the contents of tabs created by
administrators and users can only reorder the contents of tabs they created. If you
do not have the ability to modify the order of the contents, the content items will
not be displayed as links in the Table of Contents.
/**
* This is the main method to add the site, org and user tabs
along side
* the default set that was in the action model.
*/
public NmHTMLActionModel getDefaultAndDynamicTabs() {…code
here}
To add your own TabSetDelegate class you can specify the following in the
service.properties file:
<Service context="default" name="com.ptc.core.ui.tab.
TabSetDelegate">
<Option serviceClass="com.ptc.core.ui.tab.your.package.
CustomizedClassDelegate"
requestor="infoPage" selector="wt.part.WTPart"/>
</Service>
/**
* Creates, Updates, or deletes the tab by calling the @link
{JSONTabServiceAdapter}.
*
* @param data - String version of the JSON object
* @param action - will be set to one of the following values:
[create, update, delete]
* @param request
* @param response
* @throws IOException
*/
@RequestMapping(method = { RequestMethod.POST, RequestMethod.
PUT })
protected void createAndUpdateTab(@RequestParam("data") final
String data,
@RequestParam("action") final String action,
HttpServletRequest request,
HttpServletResponse response) throws IOException {…code
here…}
Importing
Importing ClientTab records is performed from the Windchill Import/Export
Management utility.
Note
If the container or user of an imported tab (whichever applies) is not present
on the destination system, that tab is not imported. A warning will be
displayed.
Packaged Samples
There is a carambola information page underCustomization ▶ Example ▶
Information Page.
http://<machineNam>/<webApp>/app/#ptc1/tcomp/
infoPage?typeIdForTypeLookup=
com.ptc.carambola.customization.examples.infoPage.Caram
bola
Checkin/Checkout
Objective
You want to be able to checkin and checkout an object.
Background
The ability to check in and checkout gives the ability to track changes to an object
by providing an iteration history of each change. Also if a user has an object
checked out, no other user may modify the object until it has been checked back
in.
In order for an object to work with the checkin/checkout common component it
must implement the wt.vc.wip.Workable interface.
Scope/Applicability/Assumptions
• The object implements either the Workable interface.
• Familiarity with the actions framework
Intended Outcome
By following these procedures you should be able to add or modify the checkin
and checkout actions.
• Checkout action (no wizard involved)
Solution
Use the Checkin/Checkout common components with your object.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Windchill “work in progress” checkin/checkout concepts.
• The actions framework in the Windchill client architecture.
• Basic development involving HTML forms, JSP, and XML.
Checkout and edit however requires additional coding. Create an additional action
definition in the actions.xml file for your object type. Name the action
“checkoutAndEdit” so that the validation framework will pick it up properly. Then
set the url attribute to point to your wizards edit jsp file.
Example:
<action name="checkoutAndEdit">
<command
class="com.ptc.core.components.forms.EditWorkableFormProcessor"
method="execute" url="netmarkets/jsp/document/edit.jsp"
windowType="popup" /
</action>
Add the appropriate entries for this action in your rbinfo file (see actions
framework documentation). In your edit jsp file you will need to add the following
tag above the wizard declaration.
<%@ taglib prefix="wip"
uri="http://www.ptc.com/windchill/taglib/workinprogress"%>
<wip:autoCheckOutItem />
This will allow the wizard to checkout the object if the object is not already
checked out.
Caution
Using this tag on wizards other than edit or without a processor that is
extending EditWorkableFormProcessor is not supported and may result in
unstable code.
Sample Code
Examples of Usage in Windchill Code
To view a sample action model with checkin/checkout actions see the document
action models (<Windchill>\codebase\config\actions\DocumentManagement-
actionmodels.xml)
Background
The Common Access Control Component was developed to provide a consistent
interface for Windchill ProjectLink and Windchill PDMLink users to view and
manipulate access control permissions on individual Windchill objects. The
feature is available in the out of the box Security Clerk through the Edit Access
Control action and also in the Create Document and Create Part wizards.
To learn more about the action and window, see the section Editing Access
Control for an Existing Object in the Windchill Help Center.
This feature for individual object instances is implemented using ad hoc ACLS.
The access component for a folder also has the additional capability of defining
permissions and propagating them throughout the folder contents.
Preferences are supported to permit sites to tailor the visibility and updatability of
individual access control permissions to meet their specific access control
requirements.
Scope/Applicability/Assumptions
This feature only applies to objects that implement the
wt.access.AdHocControlled interface. The AdHocControlled
interface holds information that controls access to a specific instance of an object
class. The ad hoc ACL specifies only positive permissions. It cannot be used to
deny access to an object. If the ad hoc ACL grants a permission that is denied in
the policy ACL, the ad hoc rule supersedes the policy rule, and the access right is
granted.
Intended Outcome
The feature may be used in two ways:
• The Edit Access Control action can be added to the object’s action model and
the action will be available in the object’s action list.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Windchill client architecture
• Basic development involving HTML forms, JSP, and tag libraries.
• The actions framework in the Windchill client architecture.
Solution Elements
Element Type Description
actionmodels.xml XML <Windchill>\codebase\
actionmodels.xml
The actionmodels file defines the actions
available in named action models.
Create<myObject>.jsp JSP The outer jsp file defining a create wizard
Customization Points
Configuring the access permissions
The permissions presented for view and update in the common access control
component are configurable at the site, org, and application container with the
preference service. At each container level, administrators can select the
permissions that members of the container will be permitted to view and
potentially update.
The initial values for the permission configurations are loaded from
<Windchill>\loadFiles\preference.foundation.xml with a
csvcategoryName of “SECURITY_PERMISSION_CATEGORY”.
Below is an example loading the initial system configuration for the Read
permission.
<csvPreferenceDefinition
handler="wt.preference.LoadPreference.createPreferenceDefinition">
<csvname>security/accessPermissionRead</csvname>
<csvvisibility>HIDDEN</csvvisibility>
<csvcategoryName>SECURITY_PERMISSION_CATEGORY</csvcategoryName>
<csvdisplayName>com.ptc.core.security.securityResource:READ</csvdisplay
Name>
<csvdescription>com.ptc.core.security.securityResource:READ</csvdescript
ion>
<csvlongDescription>com.ptc.core.security.securityResource:READ</csvlong
Description>
<csvhandler>com.ptc.windchill.enterprise.preference.handler.ChoiceMultiPr
eferenceValue
Handler:readPermission:HIDE,com.ptc.core.security.securityResource,HIDE:V
IEW,com.ptc.
core.security.securityResource,VIEW:UPDATE,com.ptc.core.security.security
Resource,
UPDATE</csvhandler>
</csvPreferenceDefinition>
<csvLinkPreferenceClientDefinition
handler="wt.preference.LoadPreference.setClientDefinitionLink">
<csvname>security/accessPermissionRead</csvname>
<csvclientName>WINDCHILL</csvclientName>
</csvLinkPreferenceClientDefinition>
Sample Code
Examples of usage in OOTB code
<jca:initializeItem operation="${createBean.create}"/>
<docmgnt:validateNameJSTag/>
<jca:wizard title="${param.titleString}">
<jca:wizardStep action="setContextWizStep" type="object"/>
<jca:wizardStep action="defineItemWizStep" type="object"/>
<jca:wizardStep action="setAttributesWizStep" type="object"
/>
<jca:wizardStep action="attachments_step" type="attachments"
/>
<jca:wizardStep action="setAccessControlWizStep"
type="object"/>
</jca:wizard>
<script type="text/javascript">
setUserSubmitFunction(submitFileContent);
</script>
<command
class="com.ptc.core.security.forms.UpdatePermissionsFormDelegate" method=
""
windowType="wizard_step"/>
</action>
Attachments
Objective
You want to add or modify the ability to add, modify, and download content from
a format content holder or content holder business object
Background
The ability to add attachments to an object is the ability to upload and associate a
file, link to a url, or describe an external location of content and associate that
content data with this object. For example you may create a document and upload
one or more files. You may also add multiple urls that point to additional
information as supporting material for a change request.
Object types such as documents implement an interface called
FormatContentHolder which allows them to associate one piece of content
as “primary content”. There can only be one primary content though. Object types
such as a change requests implement ContentHolder which allow them to
have multiple secondary content but not primary attachments. Objects that
implement FormatContentHolder however can have both primary and
secondary attachments because FormatContentHolder is a specialization of
the ContentHolder interface.
Intended Outcome
By following these procedures you should be able to add or modify the following
components to your UI.
Primary content component in a wizard (object must be a
FormatContentHolder)
Solution
Use the Attachments Common Components with customized JSP clients
associated to that object type.
Solution Elements
Element Type Description
attachments.tld Java tag Defines any common
definition component tags you will need to
use the attachments common
components.
Runtime location:
codebase\WEB-INF\tlds\
attachments.tld
AttachmentsValidation Helper. Java file Supporting methods for
class validating various attachments
related actions.
Runtime location:
codebase\WEB-INF\lib\
wncWeb.jar
AbstractAttachments Java file General form processing
SubFormProcessor.class delegate that provides shared
attachments functionality to the
primary and secondary form
processors.
Runtime location:
codebase\WEB-INF\lib\
wncWeb.jar
PrimayAttachment Java file Form processing delegate that
SubFormProcessor.class attaches primary attachments to
the object.
Runtime location:
codebase\WEB-INF\lib\
wncWeb.jar
Procedures
• Adding primary content to a wizard
To add primary attachment support to a wizard of an object that implements
the FormatContentHolder interface you will need to add the applet tag
to the main wizard jsp and the primary attachment tag to a wizard step.
On the main wizard jsp (which defines the <jca:wizard tag and the wizard
steps) add the following tag definition and
fileSelectionAndUploadApplet tag. The tag will render a tiny
invisible applet which is used for file browsing and file uploading.
<%@taglib prefix="attachments"
uri="http://www.ptc.com/windchill/taglib/attachments" %>
<attachments:fileSelectionAndUploadApplet/>v
On the wizard step you will need to add the same taglib definition above (but
not the applet tag) and the following tag. This tag will render the actual
primary attachment input components such as the file chooser or the url
inputs.
<attachments:primaryAttachment/>
• Adding secondary attachments to a wizard
To add secondary attachment support to a wizard of an object that implements
the ContentHolder interface you will need to add the applet tag to the
main wizard jsp and the attachments wizard step.
<attachments:fileSelectionAndUploadApplet/>
Inside your wizard definition (inside the <jca:wizard tags) add the
following wizard step in the order that you would like it to appear.
<jca:wizardStep action="attachments_step" type="attachments" />
Note
Attachments are not supported in Change Task wizards.
To get it on the additional attributes info page add this to your object's
attributes.jsp
<jsp:include
page="/netmarkets/jsp/attachments/attachments_table.jsp"
flush="true">
</jsp:include>
• Adding secondary attachments to an info page
On your object's attributes.jsp add the following to get the secondary
attachments to show up under the more attributes sub navigation of the info
page.
<jsp:include
page="/netmarkets/jsp/attachments/attachments_table.jsp"
flush="true">
<action name="redirect_primary_attachment"
type="attachments"/>
Customization Points
<primaryAttachment> tag attributes
Limitations
Primary content
For primary attachments code to function properly you need both the
primaryAttachment tag as well as the
fileSelectionAndUploadApplet tag, regardless of whether or not you
are using applet upload. While some behavior can be controlled by custom code
we highly recommend that you first try adjusting the site level preferences and tag
attributes to accomplish your goal before customizing your code.
The fileSelectionAndUploadApplet tag must be on the jsp that defines
the wizard but outside of the wizard tags or it will not function properly.
Secondary content
For secondary attachments code to function properly you need attachments step
defined in your wizard as well as the fileSelectionAndUploadApplet
tag, regardless of whether or not you are using applet upload. The
fileSelectionAndUploadApplet tag must be on the jsp that defines the
wizard but outside of the wizard tags or it will not function properly.
Sample Code
Examples of Usage in Windchill Code
• Secondary attachments
Excerpt from the create change request wizard (<Windchill>\
codebase\ netmarkets\jsp\changeRequest\create.jsp).
...
%><%@taglib prefix="attachments"
uri="http://www.ptc.com/windchill/taglib/attachments"
...
<jca:wizard helpSelectorKey="change_createChangeRequest"
buttonList="DefaultWizardButtonsWithSubmitPrompt"
...
...
</jca:wizard>
<attachments:fileSelectionAndUploadApplet/>
• Primary attachments
Wizard JSP
<%@taglib prefix="attachments"
uri="http://www.ptc.com/windchill/taglib/attachments" %>
...
<jca:wizard buttonList="DefaultWizardButtonsWithSubmitPrompt">
...
...
</jca:wizard>
.<attachments:fileSelectionAndUploadApplet/>
...
...
...
Intended Outcome
After reading this document you should be able to create simple and advanced
attribute panels in either edit or view mode. Specifically, you will learn how to:
• Create advanced attribute panels using Type Management layouts
• Create simple and advanced attributes panels by manually configuring the
panels in a Java builder class
• Create simple attribute panels using JSP tags
• Include your panel in a JSP page
• Convert custom attribute panels/tables created in Windchill Release 9.0 or
later to Windchill Release 10.0 attribute panels
Background
Windchill provides an attribute panel component that can be used to display
attributes of a Windchill object. Typically, these are used to display attributes in
read-only mode on object info pages or in edit mode in wizards. Attribute panels
can be configured to be a simple list of name:value pairs or they can be
configured to have a more complex layout with:
• A border
• Attribute groups, each with a title and expand-collapse capability
• Multiple columns
The former will be referred to in this document as “simple attribute panels” and
the latter as “advanced attribute panels.”
This is an example of an advanced view-only attribute panel with two groups and
multiple columns in each group:
This is an example of an editable advanced attribute panel with a single group and
one column:
Also, prior to Windchill Release 10.0, object attributes were sometimes displayed
in table format rather than in panels:
Definition of Terms
Definition of terms used in this section.
Solutions
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
• The JSP-based client architecture framework in Windchill
• The Windchill MVC builder framework
Overview
Both simple and advanced attribute panels can be created using Java builder
classes. Simple attribute panels can also be created using only JSP tags in certain
limited cases. When a builder class is used to create a panel for a TypeManaged
object, the contents and configuration of the panel can be defined in a layout in the
Type and Attribute Management utility and retrieved by the builder class.
Alternatively, the contents and configuration of the panel can also be defined in
the builder itself. The recommended approach is to:
• Use a layout-based based panel created by a Java builder whenever possible.
This provides:
○ easier customization
○ a UI for ease of configuration
○ greater reusability
○ a more consistent product
• Use a non-layout based panel created by a Java builder if:
○ The object type being displayed is not TypeManaged or
○ The type is TypeManaged but layouts are already defined for all related
screen types and none are appropriate for your purpose
• Use a JSP-tag based panel only if:
○ You want to create a simple attributes panel and
○ You only want to display a few attributes which do not require complex
configurations and
○ You don’t want the overhead of creating a builder class
The system provides OOTB builders for several layout-based advanced attribute
panels used for common, shared actions. These actions are:
To display these panels you just specify the appropriate component builder id in
the URL or action used to generate the panel on your page. You do not need to
write any Java code or JSPs. The system also provides OOTB builders for the
layout-based “Attributes” panels in object create and edit wizards that can be
displayed by using the common step actions for wizards.
To display a panel for a different layout or create a manually-configured panel you
can extend an existing Java builder class.
The decision diagram below provides general guidelines for how you should
determine which builder to use for your panel, with references to the section of
this document that describes the builder.
Note
For a few objects the system has defined subclasses of
PrimaryAttributesBuilder for the default builder.
Extending AbstractAttributesComponentBuilder
Set the desired properties on the panel config. See Customization Points on
page 358 for configuration points. Do not set the component mode as it
will be overridden by the parent class. Also, do not set the
ComponentType in this method, that can be done in step 2.
b. Create the attribute and group configs.
The label is the title that will be displayed in the UI and should be
localized from a resource file if appropriate:
Extending AbstractComponentBuilder
You will need to implement two methods in your builder:
• ComponentConfig buildComponentConfig(ComponentParams params)
• Object buildComponentData(ComponentConfig config, ComponentParams
params)
buildComponentConfig()
This can be implemented as described in Procedure – Creating the Attribute Panel
on page 347 above except that you will also need to set the ComponentMode
and ComponentType of the panel in this method. You do that by calling the
following methods on the AttributePanelConfig :
setComponentMode(ComponentMode)
setComponentType(ComponentType)
This is also where you should set a custom view JSP, if desired.
The name of the descriptor can be any name that identifies your panel. It will be
used as the name of the variable in the JSP context that holds the panel descriptor
object.
The value for <name of the data model> can be any name you wish to
assign to your model. It will be used as the name of a scoped variable in the JSP
context that will hold the created data model.
The value for <name of the descriptor> should be that used in your
describePropertyPanel tag.
The serviceName and methodName parameters specify a service method that
should be called to acquire the datum object for the model. The
addServiceArgument subtag can be used to pass parameters to the service
method. Typically, the StandardPersistenceManager.refresh()
method is used to acquire a Persistable for the daum object of view-only panels.
For example:
<jca:getModel var="propertyModel" descriptor="${propertyPanelDesc}
"serviceName="wt.fc.StandardPersistenceManager" methodName="refresh">
<jca:addServiceArgument value="${commandBean.primaryOid.oid}
" type="wt.fc.ObjectIdentifier" />
</jca:getModel>
The value for <name of the data model> should be that used in your getModel tag.
General Procedures
How to Annotate Your Custom Builder Class
You should annotate your builder class with the component builder id you will use
for your panel. You should also include a TypeBased annotation if you want to
use different builders for different object types for the same component builder id.
For example:
@ComponentBuilder(“exampleBuilderId”)
@TypeBased(value = "com.acme.SomeType")
public class ExamplePanelBuilder extends TypedAttributesPanelBuilder
You could also modify the view to use a custom JSP if you want to display other
components on the page or include additional javascript. The path name of the JSP
passed to the setView() method should be relative to <Windchill>/
codebase./WEB-INF/jsp.
To display your advanced panel in your custom JSP use the following tag for an
advanced panel:
<mvc:attributePanel/>
You should include the following taglib directive in your custom JSP:
<%@ taglib uri="http://www.ptc.com/windchill/taglib/jcaMvc" prefix=
"mvc"%>
Note that any JSP page that renders a MVC component should include the
following directive before rendering any page content:
%@include file="/netmarkets/jsp/util/begin_comp.jspf"%
These should be used in lieu of any other include directives for *begin* or
*end* files.
See Client Architecture Action Framework Overview on page 474 for more
information on actions and action attributes.
Example action tag:
<%@ tagliburi="http://www.ptc.com/windchill/taglib/components" prefix=
"jca"%>
.
.
.
<jca:action actionName="myAttributePanel" actionType="object" showIcon=
"false”/>
See the javadoc for the action tag for more information on the available tag
attributes.
An alternative way to include a link to your panel is to use an <a> tag with a href
constructed using the getComponentURL tag or
getTypeBasedComponentURL tag. The former would be used when there is
a single builder for a component builder id. The latter would be used when there
are alternative builders for the builder id based on the type of the panel object. For
example:
%@page import="com.ptc.netmarkets.util.misc.NetmarketURL"%
<%@ taglib uri="http://www.ptc.com/windchill/taglib/mvc" prefix="mvc"%>
.
.
.
<a href="<%=NetmarketURL.APPPREFIX%>${mvc:getTypeBasedComponentURL’
(myPanelComponent)}">
Customization Points
AttributePanelConfig Properties
The following parameters may be set using methods on the
AttributePanelConfig class.
GroupConfig Properties
The following parameters are applicable to AttributeGroupConfigs and
may be set using methods on the GroupConfig class.
AttributeConfig Properties
The following properties are applicable to AttributeConfigs and may be set
using methods on that class. Many additional properties are available on the
parent interface PropertyConfig. See Attribute Customization on page 615
for more information on these.
Sample Code
Example of Usage in Windchill Code
Additional Resources
Related Customization Documentation
• Windchill Client Architecture Overview on page 223
Action Framework for Windchill Client Architecture on page 474
NmObject Utilities on page 550
• Attribute Customization on page 615
Windchill Client Architecture Common Objects Overview on page 236
Acquiring Data via Info*Engine on page 544
Customizing Role-Based UI Functions - Attribute Visibility on page 447
Customizing Information Page Components on page 931
• Building Wizards to Create a Single Object on page 844
• Building Wizards to Edit a Single Object on page 866
Location of Example
To navigate to this example in the produce go to Customization ▶ Component
Catalog ▶ Attribute Panel ▶ Advanced Attribute Panel.
Location of Example
To navigate to this example in the produce go to Customization ▶ Component
Catalog ▶ Attribute Panel ▶ Advanced Attribute Panel in a Wizard.
The action tag used to invoke the action from the JSP adds the parameters
“tlnAction” and “tlnType” to the infoPage URL to tell the system to
navigate to the tab in the Carambola information page that has the
“attributePanel” action component.
<%
HashMap<String,String> advPanelInfoPageParams = new
HashMap<String,String>();
// automatically forward to the tab for attribute panel.
advPanelInfoPageParams.put("tlnAction", "attributePanel");
advPanelInfoPageParams.put("tlnType","carambola"); %>
<jca:action actionName="infoPageExample" actionType="carambola"
button="false" params="<%=advPanelInfoPageParams%>" shellURL="true"/>
Location of Example
To navigate to this example in the produce go to Customization ▶ Component
Catalog ▶ Attribute Panel ▶ Advanced Attribute Panel on an Information Page.
To reset the title of the group the builder calls the setLabel() method on the
group config. If it did not reset the title, the group would have the title specified in
the Type and Attribute Management utility.
Like the example Advanced Attribute Panel on an Information Page on page 369,
the attribute panel is displayed on a new tab of the Poem information page by
specifying “tlnaction” and “tlntype” parameters on the info page URL.
See Advanced Attribute Panel on an Information Page on page 369for more
information on how this is done.
See Solution – Create an Advanced Attribute Panel Using Any Layout Defined in
the Type and Attribute Management Utility on page 346 for more information on
creating layout-based attribute panels.
Location of Example
To navigate to this example in the product go to Customization ▶ Component
Catalog ▶ Attribute Panel ▶ Advanced Panel with Modified Context Object.
Location of Example
To navigate to this example in the produce go to Customization ▶ Component
Catalog ▶ Attribute Panel ▶ Simple Attribute Panel Using a Java Builder.
Location of Example
To navigate to this example in the produce go to Customization ▶ Component
Catalog ▶ Attribute Panel ▶ Simple Attribute Panel Using JSP Tags.
Panel 1
This is a composite component that displays:
• A simple panel containing a single attribute – the name of the container for the
new object
• The type of object being created
○ Note that if this object type had subtypes, a type picker would be displayed
here instead of a read-only field
• A simple panel with an input field for Organization Id (only displayed if the
preference Display ▶ Expose Organization is set to “Yes”)
• An advanced panel titled Attributes, which contains most of the non-driver
attributes of the new object. This panel is based on the layout for the screen
type “Create New” (ScreenDefinitionName.CREATE) for the parent
WTDocument type.
This composite panel is created automatically by the JCA framework when we
included the contents of the file <Windchill>/codebase/WEB-INF/jsp/
object/defineItemAttributesWizStep.jsp in our wizard step JSP.
That file is the default JSP for the Set Attributes wizard step. If we had not wanted
to include additional panels in this wizard step, we could have used the default
action “defineItemAttributesWizStep” in the wizardStep tag and
not had to write any JSPs or Java code for the wizard.
This statement tells the JCA framework to look for a Java builder class with the
component builder id
“carambola.attributePanel.WizardPanelForEnabledAndDe-
partment.” It will find the builder class
EnabledAndDepartmentPanelBuilder, which will configure the panel,
acquire the data for it, and set the JSP that will display the panel.
Some things to note about this builder are:
• The buildComponentData() method returns a TypeInstance for a new
Novel object. If the panel object is a Windchill business object, it is important
that datum object be a TypeInstance so that any constraints defined for the
attributes are captured and made available to the data utilities.
• The panel component type is set to ComponentType.WIZARD_
ATTRIBUTES_TABLE. This is needed so that the HTML names of the input
fields are created such that the framework can identify the attributes it needs to
set on the object after the wizard is submitted.
See Solution – Create a Simple or Advanced Attribute Panel Using a
Configuration Created in a Java Builder Class on page 347 for more information
about this technique for creating attribute panels.
Panel 3
This is a simple attribute panel with one property, “Copyrighted,” that is not
an attribute of the Novel object type. You might use this technique when you want
to capture some additional information from the user besides the object’s
attributes. Note that because the Copyrighted information is not an object
attribute, a custom FormProcessor or FormProcessorDelegate would
be needed to handle this information when the wizard is submitted.
This panel is created by the following statement in the step JSP:
<jsp:include page="${mvc:getComponentURL
('carambola.attributePanel.WizardPanelForCopyrightInfo')}"/>
Just as in the previous example, this statement tells the JCA framework to call a
MVC Java builder class, which, in this case, is the class
CopyrightAttributePanelBuilder. Some things to note about this
example builder are:
Panel 4
This is a simple attribute panel containing one attribute of the panel object type. In
this case the panel was created using JSP tags in the wizard step JSP.
See Solution - Create a Simple Panel Using JSP Tags on page 351 for more
information about this technique for creating attribute panels.
Background
Before you can use packages within a context, you must first enable packages for
that context. When you enables packages for a given context, the system loads a
site-wide package template XML file. The package template file contains package
specific roles that are applied to the container team, the default domain structure
for packages, and package-related policies.
The default domain structure will create a Package domain specific to the current
context. All packages created within the context, as well as all of the objects
created within the packages (collections, folders, documents, links, and deliveries)
will use this package domain by default. Out of the box, the package domain is
Private. This means that it won't inherit any policies from the container's default
domain.
Scope/Applicability/Assumptions
This guide assumes that you want to customize the default roles, domain structure,
or access control policy rules associated with Packages across all contexts. You
should be familiar with managing Packages, teams, and administering access
control for Windchill business objects.
Intended Outcome
Customize the default roles, domain structure, or access control policy rules
associated with Packages across all contexts.
Solution
Use the package template XML file to customize the default roles, domain
structure, and access control policy rules associated with Packages across all
contexts.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Administering Packages
• Creating business XML files for templates
• Windchill team concepts
• Administering Domains and Policies
Solution Elements
Element Type Description
packageTemplate.xml XML The XML file that
contains the roles, domain
structure, and policies
associated with Packages.
This file is loaded when
you enable packages for a
context.
Location: <Windchill
>/loadXMLFiles
packageSharedTeamTem- XML The XML file that
plate contains the shared team
roles. This file is loaded
in addition to the
packageTemplate.xml file
when you enable
packages for a context
that is using a shared
team that isn’t extended.
Location: <Windchill
>/loadXMLFiles
Sample Code
Additional Resources
Report Location
From the Navigator browse to Customization ▶ Tools ▶ Action
Search supports:
• Multiple search parameters
• Regular expressions
• Case-insensitive matching
Search Examples:
• For Label (aka Description):
○ remove ==> Matches: "remove", "list_delete", "related_delete_described_
part", etc.
• For Action Name :
○ remov.* ==> Matches: "remove", "remove_deliverable", "removeUses",
etc.
○ r[a-z]* ==> Matches: "reply", "REVISEITEMS", "reassignLC", etc.
Features
• New actions can be created from the Actions table by selecting Create Action
from the Actions menu.
• Actions can be copied to Clipboard from the Actions table.
• “Select Required” is added as a column to the action report.
• “Icon Path” is added as a column to the action report.
• “Select Required” is added as a property to the action details page.
Ability to persist the user changes in a new location (coming from
wt.properties) and change in framework to give precedence to these new
persisted files. The modified action changes are saved to xml. Property to be
added in the wt.properties for actions is
com.ptc.netmarkets.util.misc.customActions. The value for
the property would be complete path to the custom xml along with the file
name. Example entry in wt.properties on Windows:
com.ptc.netmarkets.util.misc.customActions=D\
:\\myCustomActions.xml. If the property is not specified, user changes
would be persisted in: <wt-codebase>/config/actions/custom-
actions.xml
Report Location
From the Navigator browse to Customization ▶ Tools ▶ Action Model
Search supports:
• Multiple search parameters
• Regular expressions
• Case-insensitive matching
Search Examples
• For Action Model:
○ Default.* ==> Matches: "DefaultWizardButtons",
"DefaultWizardButtons", etc.
○ .*actions ==> Matches: "dti actions", "bookmark actions", "workitem
actions", etc.
○ [a-z]*s ==> Matches: "ScmiWizardButtons", "relatedItems",
"EditWizardButtons", etc.
○ .* ==> Matches: everything
• For Model File:
○ Files must be located under <Windchill>\codebase\config\
actions
To display the full action model report for one of the displayed action models,
click the icon for it:
The “Description” attribute of the action model represents the text entered for the
“description” subtag of the actionmodel tag, if any.
New Features
• Ability to create a new action (prototype) or remove an existing action in
action model table is added.
• Clipboard paste on ActionModel table.
• “Separator” action is added into the action model display.
• Reordering of actions in action model can be done using the drag and drop
functionality.
• Ability to persist the user changes made in an action model to a new location
(coming from wt.properties) and Change in framework to give precedence to
these new persisted files. The modified action models are saved to xml. A
property required to be added in the wt.properties for action models is
com.ptc.netmarkets.util.misc.customActionModels. The
value for the property would be complete path to the custom action model
xml. Example entry in wt.properties on Windows: com.ptc.netmarkets.util.
misc.customActionModels=D\:\\myCustomActionModels.xml
• If the property is not specified, user changes would be persisted in <wt-
codebase>/config/actions/custom-actionModels.xml
• Inline actions can be created in an action model. Their scope would be limited
to only that action model.
Results Table
• JCA ID
• JS ID
• Schema ID
• View Wizard Label
• Table Column Label
• Data Utility
• componentRB Label
• Column Descriptor Factory Label
• Introspected Label
Note
If there is no information for the property of a particular attribute, the cell is
shown blank.
The factory looks in this xml file to see if the requested logical form has an
entry specified for the type that was passed in by the user. If there isn't an
entry for the requested type, it sees if there is an entry for any of the type's
supertypes. Multiple inheritance conflicts are resolved by two rules:
a. Parent classes win over parent interfaces
b. Parent interfaces win by alphabetical order (so "java.util.Map" wins
over "java.util.Set"). (more configurable solution is possible).
3. If there wasn't a matching entry in LogicalAttributes.xml, then the
factory does introspection to try and find a match. This works by getting a list
of all AttributeTypeIdentifiers defined for the requested type, and
seeing if the logical form matches any of the attribute names in the list.
Report Output
The report output has four columns. The first two columns map an attribute's
logical form to the external form that the factor will return. The third column
shows where the factory got the external form – either from
logicalIdentifier.properties, LogicalAttributes.xml, or
Introspection. The fourth column shows the business field identifier.
• Detailed Information Page: The detailed information page for each object has
two tabs, one for the Database Information and one for the Java Information.
Only objects that have a corresponding database table will have a Database
Information tab.
• Database Information: The Database Information tab has four sections of
information about the object's database table.
• Table Attributes: A list of single valued attributes that describe the database
table. At the moment, the only value is the Table Name.
Column Descriptors
A table of Column Descriptors. There is one row for each column in the database
table. Within the Windchill meta data, this information is stored in a "Column
Descriptor" class, thus the name "Column Descriptor".
Java Information
The Java Information tab has seven sections of information about the object's Java
class.
Attributes
A list of single valued attributes that describe the class.
Attribute Description
Display Name The name of the object as it is exposed
to end users.
Icon An image of the icon used to represent
instances of this object in the Windchill
UI
Class Name The fully qualified Java class name
Persistable "Yes" or "No". Only concrete,
persistable classes will have a
corresponding database table.
Parent Class The direct, Java, parent class. This will
be a link to that class's information
page (if the page exists).
• UML Diagram: A UML diagram for the class (not all classes have UML
diagrams).
• Javadoc: A link to the Javadoc for this class. Will only appear if the class itself
is included in the Windchill Supported API.
Debugging
This section describes how to activate and use the jcaDebug, jsDebug, Log4j
logging, and log4javascript logging.
Using jcaDebug
To enable the JCA debug feature, simply add “&jcaDebug=true” to the URL
of a Windchill page displayed in the browser’s address field, as described below.
You can enable jcaDebug from Customization ▶ Tools ▶ jcaDebug.
Entire Shell
To put jcaDebug output on the entire Windchill page, including the Navigator and
header, put the jcaDebug parameter before the # token. Use a “?” since it becomes
the first parameter. http://<server>/Windchill/app/?jcaDebug=
true#ptc1/tcomp/...
Once added, the jcaDebug parameter will automatically be applied to all
subsequent Windchill pages. To turn off the feature, remove the jcaDebug
parameter from the URL of the current page.
In some cases, a table that should display this debug information will not show
any data rows at all, even though the object count at the top contains non-zero
values. If this occurs, you should paste the URL into a new browser session.
Actions Menu
The following information is shown:
1. The object type and action name from the action definition are shown for each
item in the menu. To see more details about the action you can go to the action
report for that type and name. For example http://<server>/Windchill/app/
#ptc1/carambola/tools/actionReport/actionDetails?actionName=
addToBaselineSingle&objectType=baseline
2. The Java validator class for each action
3. For template processor actions only, the URLActionDelegate for the action
4. The name of the action model used for the menu. When clicked this action
opens the action model report. For example http://<server>/Windchillapp/
#/ptc1/carambola/tools/actionReport/actionModelDetails?actionModelName=
epmdocuments+details+page+actions
Note
To ensure patched js files would take effect regardless of browser caching,
PTC.navigation.loadScript() adds a cache buster URL parameter to force
reload of the js files at least every Sunday.
JavaScript Logging
Windchill now includes a JavaScript logging package, called log4javascript,
which is a third-party JavaScript library from log4javascript.
Turning on Logging
Logging may be turned on in one of the following ways:
• Add a jsLog URL parameter
To turn on global logging, append jsLog=true to the end of a Windchill URL
in the browser’s address field:
http://ah-lisa.ptcnet.ptc.com:1600/Windchill/app/#ptc1/comp/
home.overview?
oid=OR%3Awt.org. WTUser%3A21639&u8=1&jsLog=true
This is the same as turning on TRACE level logging on the PTC logger.
• Programmatically (in JavaScript code or in the console)
To programmatically turn on logging, include the following:
var mylogger = log4javascript.getLogger("PTC.mypackage");
mylogger.setLevel(log4javascript.Level.TRACE);
• Using a UI
Enter the URL address “javascript:PTC.log.startLogger()" to
launch a UI that lets you enable logging. Just hit "Ok" to enable all loggers or
enter a logger name to enable a specific logger.
• From the Tools Page
You can enable jsLog from Customization ▶ Tools ▶ jsLog.
See additional information in the javadoc for the PTC.log object JavaScript.
Log4j
Log4j loggers can be enabled from the UI, accessible from the Tools page. Note
that this feature works only for Site Administrators. This and many other site tools
are also available under Site ▶ Utilities ▶ Server Status ▶ Monitoring Tools.
Objective
The UI Component Validation Service was created to give Windchill clients a
central service to call to perform validation for actions and other components
appearing in the Windchill UI. Calls to the service and interpretation of the results
should be managed by many of the common components developed in release 9.0.
The main responsibility for an application developer would be development of
Validator classes that are called by the validation service to validate a specific
action or UI component. This documentation outlines the process and best
practices for authoring Validator classes.
Applicability
This documentation should be used by a developer who is responsible for
authoring one or more Validators to determine whether or not an action or UI
component is valid on a given page/context/etc. The documentation should walk
through an example of each type of validation operation that a Validator could be
called upon to perform.
Structure
All of the classes in the UI Validation Service (except where noted) are defined in
the com.ptc.core.ui.validation package.
A Validator developer will not need to interact with all of the classes in this
diagram, but many of them are applicable. The various classes will be discussed
throughout this document, but to begin with, a developer writing a Validator
should always define their Validator class to extend
DefaultUIComponentValidator.
Note
It is also important to note that as requirements evolve, these classes may be
updated. To get the latest set of methods and attributes defined in each of the
classes see the Windchill Javadoc.
Collaborations
Validator developers need to collaborate with common component developers and
other callers of the Validation Service. This collaboration is necessary to ensure
that a caller of the service is passing all of the data to the service that a given
Validator will need to perform validation. It is strongly recommended that
Validator developers include a list of the data required in a given validation
method in that method’s Javadoc. It is also helpful to include a list of Validation
keys (action names) that the method is designed to account for. For example:
public class DefaultWIPValidator extends DefaultUIComponentValidator
{
…
/**
* This implementation of performLimitedPreValidation will check the
checkout
* state of all the Workable objects in the ValidationCriteria's
targetObjects
* WTCollection, and base its validation results on whether an object in
the
* given state can have the specified action performed on it. (e.g., an
object
* in the checked-in state can not have an undo checkout action performed
on it)
*
* At a minimum, a caller of this method should provide the targetObjects
* WTCollection in the validationCriteria argument.
*
* The expected validationKey arguments for this method are:
* checkin
* checkout
* undocheckout
*
* <BR><BR><B>Supported API: </B>false
*
* @param validationKey The String identifying the action or
component
being validated.
* @param validationCriteria Object holding information required to
perform
validation tasks.
Consequences
By using this documentation as a reference, developers should create consistent,
performant Validators. A caller of the validation service should be confident that
whatever action or UI component they are validating will be validated in a
consistent manner.
Implementation
Overview
It is probably helpful to begin with a definition of the term validation. For the
purposes of this discussion, the term validation refers to activities performed to
determine what a user can see or do. For example:
• Should we display the “Create Part” action?
• Should we allow the checkout of this object?
• Is everything the user entered in this create wizard OK?
For the purposes of our discussion, validation can be broken down into three
broad categories:
Pre-Validation
• Attempts to answer the questions: “Should something appear to the user in the
UI? And, if so, should it be editable/selectable?”
• For example, Should we display and enable the “Create Part” action for user A
in container B?
• Pre-Validation can be performed for actions or other UI components (status
glyphs, attributes, tables, etc.)
Post-Submit Validation
• Attempts to answer the question: “is the data the user just entered valid?”
• For example, When the user clicks ‘Next’ in the “Create Part” wizard, are we
going to let them go to the next step, or do they need to modify some data (e.
g., name, number) in the current step?
The UI Component (Action) Validation Service exposes one or more APIs for
each of the types of validation listed above.
From a high level, a common component or some other client invokes a validation
API on the Validation Service, passing one or more validation keys (which can be
thought of as an action name, like create, for instance) and a UIValidationCriteria
bean, which contains data known by the client that is required to perform
validation. The Validation Service uses the validation key(s) to perform a lookup
and identify the Validator class(es) that should be called to carry out the validation
activity. The service then passes the key and UIValidationCriteria on to the
identified Validator(s) and awaits a (set of) result(s). When the service has the
result(s) from the Validator(s), it (creates a bundle of results and) returns it to the
client.
Packaging/Modularization
All of the classes related to the UI Component Validation Service are packaged in
com.ptc.core.ui.validation. Their source is located in the module \Windchill\src
\com\ptc\core\ui\validation. It is strongly recommended that any time a developer
is doing Validator development, they update all of the files in this directory and
compile the latest versions of the Java classes.
Developers writing Validators should put their Validator classes in a package or
module that is meaningful for the action(s)/UI component(s) that the Validator
validates.
For those methods which you do not override, the default behavior (always
enable/permit) will be inherited from the DefaultUIComponentValidator class.
You will also need to create a properties entry to associate your Validator class
with a particular validation key (action). The validation service uses these entries
to find the right Validator for a given validation key (action). The entry will go in
service.properties, or your application team’s service properties file (ask your
group lead where you should put your entry), and should have this format:
wt.services/rsc/default/com.ptc.core.ui.UIComponentValidator/
<validationKey>/
null/0=com.ptc.my.validators.MyValidator
Where <validationKey> is the validation key for your action/component and the
right-side value is the fully-qualified class name of your Validator.
There are three types of checks you should never have to perform in your
Validator implementations. These checks are performed by the validation service
before the Validators are called. They include:
• Role-based checking (visibility of actions based on input into the RBUI
system, which is not to be confused with access control checking, which needs
to be done in the Validators.)
Sample Code
Note
This source code can be found at the following location: <Windchill>\
src\com\ptc\windchill\enterprise\ wip\
DefaultWIPValidator.java
/* bcwti
*
* Copyright (c) 2004 Parametric Technology Corporation (PTC). All
Rights
* Reserved.
*
* This software is the confidential and proprietary information
of PTC.
* You shall not disclose such confidential information and shall
use it
* only in accordance with the terms of the license agreement.
*
* ecwti
*/
package com.ptc.windchill.enterprise.wip;
import com.ptc.core.ui.validation.*;
import java.lang.ClassNotFoundException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import org.apache.log4j.Logger;
import wt.access.AccessPermission;
import wt.access.AccessControlHelper;
import wt.epm.workspaces.EPMWorkspaceHelper;
import wt.fc.Persistable;
import wt.fc.ReferenceFactory;
import wt.fc.WTReference;
import wt.fc.collections.WTArrayList;
/**
* This implementation of performLimitedPreValidation will
* check the checkout state of all the Workable objects
* in the ValidationCriteria's targetObjects
* WTCollection, and base its validation results on whether
* an object in the given state can have the specified
* action performed on it. (e.g., an object
* in the checked-in state can not have an undo checkout
* action performed on it)
*
* At a minimum, a caller of this method should provide the
* targetObjects
* WTCollection in the validationCriteria argument.
*
* The expected validationKey arguments for this method are:
* checkin
* checkout
* undocheckout
*
* <BR><BR><B>Supported API: </B>false
*
* @param validationKey The String identifying the action
if (validationKey.equalsIgnoreCase("checkin") || validationKey.
equals
IgnoreCase("undocheckout")){
result = performCheckinValidation(validationKey, workable, SELE
CTED,
(WTUser)(validationCriteria.getUser().getPrincipal()));
}
else if (validationKey.equalsIgnoreCase("checkout")){
result = performCheckoutValidation(validationKey, workable, SELE
CTED);
}
UIValidationResultSet resultSet =
performWIPValidation(validationKey,
validationCriteria, locale, SELECTED);
// ***NOTE:
// There is no post-submit validation for the WIP actions
// (checkin, checkout, undocheckout), since there is
// no wizard launched when one of the actions
// is performed. Therefore, there is no need to define a
// validateFormSubmission method in this class.
//
// public UIValidationResult validateFormSubmission (String
validationKey,
// UIValidaitonCriteria validationCriteria, Locale locale)
while (workableIter.hasNext()){
workable = (Workable)workableIter.next();
if (validationType.equals(LIMITED)){
WorkInProgressState state = workable.getCheckoutInfo().getState();
if (state.equals(WorkInProgressState.CHECKED_OUT) || state.equals(
WorkInProgressState.
CHECKED_OUT_TO_SANDBOX)){
return new UIValidationResult(validationKey, wtRef, UIValidation
Status.ENABLED, null);
}
else{
return new UIValidationResult(validationKey, wtRef, UIValidation
Status.DISABLED, null);
}
}
if (validationType.equals(FULL)){
goodStatus = UIValidationStatus.ENABLED;
badStatus = UIValidationStatus.DISABLED;
}
else{
if (isNewInWorkspace(orig)){
return new UIValidationResult(validationKey, wtRef, badStatus,
null);
}
}
if (WorkInProgressHelper.isCheckedOut(workable, user) ||
(WorkInProgressHelper.isCheckedOut(workable) &&
WTContainerHelper.service.isAdministrator(((WTContained)
workable).
getContainerReference(), user))){
return new UIValidationResult(validationKey, wtRef, goodStatus,
null);
}
else{
return new UIValidationResult(validationKey, wtRef, badStatus,
null);
}
}
return new UIValidationResult(validationKey, wtRef,
UIValidationStatus.
ENABLED, null);
}
if (validationType.equals(LIMITED)){
WorkInProgressState state = workable.getCheckoutInfo().getState();
if (state.equals(WorkInProgressState.CHECKED_OUT) || state.equals(
WorkInProgress
if (validationType.equals(FULL)){
goodStatus = UIValidationStatus.ENABLED;
badStatus = UIValidationStatus.DISABLED;
}
else{
goodStatus = UIValidationStatus.PERMITTED;
badStatus = UIValidationStatus.DENIED;
}
if (isNewInWorkspace(workable)){
return new UIValidationResult(validationKey, wtRef, badStatus,
null);
}
if ((AccessControlHelper.manager.hasAccess(workable, AccessPermis
sion.MODIFY)) &&
(!WorkInProgressHelper.isCheckedOut(workable) &&
(VersionControlHelper.isLatestIteration((Iterated)workable)) &&
(!SandboxHelper.isCheckedOutToSandbox(workable)))){
return new UIValidationResult(validationKey, wtRef, goodStatus,
null);
}
else{
return new UIValidationResult(validationKey, wtRef, badStatus,
null);
}
}
return new UIValidationResult(validationKey, wtRef,
UIValidationStat
us.ENABLED, null);
}
try{
return refFactory.getReference(workable);
}
catch(WTException wte){
return null;
}
}
try{
targetObjects.removeAll(Class.forName("wt.vc.wip.Workable"),
true);
}
catch(ClassNotFoundException cnfe){
// do nothing
}
Iterator nonWorkableIter = targetObjects.referenceIterator();
WTReference wtRef = null;
while(nonWorkableIter.hasNext()){
wtRef = (WTReference)nonWorkableIter.next();
resultSet.addResult(new UIValidationResult(validationKey, wtRef,
status,
null));
}
return resultSet;
}
}
Known Uses
This documentation should be used by any developer responsible for writing a
Validator for an action or UI component.
Background
The two pane component is a way to present the data from two JSP’s into one
logical UI component. The panes can be laid out horizontally or vertically. There’s
a separator between the two panes (left/right or top/bottom) that allows the user to
dynamically change the size of the panes.
Scope/Applicability/Assumptions
This information should be applied by a developer or customizer who is
responsible for laying out the two pane component for their functional area in
Windchill.
This documentation assumes that :
• You have some service method to provide data for the two pane component.
Intended Outcome
• Two Pane - Horizontal
Solution
Use the two pane common component tag, renderTwoPanes. This is included in
the JCA common components library (http://www.ptc.com/windchill/taglib/
components).
Prerequisite knowledge
To use the two pane component, you need to have an understanding of the
following:
• JSPs, tag libraries, and JSTL
• The JSP-based client architecture framework in Windchill
Solution Elements
Using this component, a developer needs to configure the left and right pane JSP,
while the layout of the page is provided by the renderTwoPanes taglib.
Element Type Description
RenderTwoPanesTag.java Java class The tag that renders out
the two pane component
in a JSP
navigation.jsfrag JavaScript Fragment Renders the component to
the DOM
<your_left_pane>.jsp JSP The JSP to have
displayed in the left or top
pane, depending on the
Note
Ensure the value for the “renderTo” attribute matches the id given to the
DIV element in previous step.
PTC.navigation.loadViewPort = function(pageItems){
Customization Points
renderTwoPanes tag attributes
The renderTwoPanes tag is a custom JSP tag that you insert in the JSP.
Limitations
When the left or right pane is resized, some of the components within that pane
may not get resized properly.
The underlying framework manages the layout of the components it knows about
in its component hierarchy, so that (among other things) it can recalculate the
layout on resize events. For example, when a resize event happens, it would
recalculate the layout of its children, and those children’s children, and so on.
Because the two pane component simply renders its contents to the DIV
corresponding to the pane, and does not actually add its contents as a child of the
pane’s panel, nesting components (especially those components that are containers
to house other components) within a pane may not behave as expected.
if(button != undefined) {
var cp = PTC.getCmp(PTC.navigation.cardManager);
var contentPanel;
var renderToDiv = 'twoPanes_RIGHTPANE2';
var options = {
asynchronous: false,
method: 'get',
parameters: {
buttonId: button.innerHTML,
dynamicUpdate: true
}
};
var transport = requestHandler.doRequest(getBaseHref()
+
'netmarkets/jsp/carambola/customization/examples/
two
PanePanels/rightOrBottomPane.jsp', options);
<jsp:include page="/netmarkets/jsp/wp/wp_exp_attachments.jsp"
flush="true" />
Solution Elements
To make the two tables as different drag and drop zones, you must add the
following attributes:
• class="dropZone" : Identifies that this div is used as a drop zone.
Results
After adding the required attributes, the jsp looks like this:
<div class="dropZone" targetTableId="table_attachments.list.
editable_TABLE">
<jsp:include page="/netmarkets/jsp/attachments/attachments_step.
jsp"
flush="true" />
</div>
<br><br>
<div class="dropZone targetTableId="wp.attachments.list.editable">
<jsp:include page="/netmarkets/jsp/wp/wp_exp_attachments.jsp"
flush="true" />
</div>
The New Package wizard now looks like this:
This chapter describes user interface customizations that are independent of any
particular Windchill client technology.
Background
The role-based UI functionality enables administrators to optimize the number of
actions presented to users, so as not to confuse users by seeing actions they don’t
need or use for their role. Initially this support was just for container managers (in
particular, project managers). It has been extended to a concept called profiles
which sets action visibility at the site or organization level.
A site administrator, organization administrator or container administrator can
specify which users have visibility to the actions defined. For site and organization
administrators this can be done through profiles. Profiles can be created at Site-
>Profiles or Org->Profiles. The actions defined will be presented with their
default settings, and the administrator can choose to hide those actions. The
administrator can then specify which participants (users, groups, orgs) belong to
the profile. All members of the profile will have that visibility. If a member is in
multiple profiles, the greatest visibility is provided.
At the container level, the administrator can specify the visibility based on user
roles. Anyone in those roles will have the visibility specified. Container-level role
visibility will override any profile in which the member might be a participant.
See the section About Configuring Action Visibility by Role in the Windchill
Help Center for more details about profile and role-based visibility administration.
Scope/Applicability/Assumptions
• The role-based visibility administration capability is turned on, that is, the
preference com.ptc.netmarkets.roleAccess.enabled is set to
true. The customization can be performed while the capability is turned off,
but the results will not appear in the UI until the capability is turned on.
• The customizer can manage both OOTB UI components and customized UI
components with this capability.
Intended Outcome
When configuring visibility by roles and configuring profiles, the administrator is
presented with a list of UI components that can be managed. The administrator is
unable to manage the visibility for any UI components that are not included in this
list.
Solution
Modify the roleaccessprefs.xml file (and associated files as needed).
Note
The Additional Resources section below includes references to many or all of
these subjects.
Solution Elements
Element Type Description
*actionModels.xml XML Files which define the models where
actions are used. If an action is not already
defined in a model, one will need to be
created for the validation code to find the
action and properly set visibility.
actionmodels.xml is located in <Windchill
s>/codebase; other *actionmodels.xml files
are generally in <Windchill>/codebase
/config/actions
*actions.xml XML Files where actions and other UI
components are defined. Actions are
optionally given a uicomponent value.
actions.xml is located in <Windchill>/
codebase /config/actions along
with other *actions.xml files.
Note
This example assumes that the Create Folder action is not already available for
role-based visibility management; in the actual product, it is available out of
the box.
Note
See the section on the uic element below for attribute descriptions.
Note
For actions that are valid for multiple tab types, put the entry under all the
sections you want it to affect.
Caution
Follow best practices in backing up your XML files when customizing
them.
Customization Points
uic Element
Each UIC in roleaccessprefs.xml represents a UIComponent or action to be
controlled.
Parameter Default Possible Req? Description
Value Values
name n/a string Y The name of the UI component.
This must match the value of
the uicomponent (or name)
attribute on an action element in
actions.xml. This must also
match the value of a resource
entry constant in the resource
bundle.
order n/a Integer N The position of this UI
component in the wizard. UI
components with lower
40.constant=CUSTOMIZED_TAB
As a result, the “Create Folders” entry in the Configure Roles and Create Profile
pages will affect the visibility for both folder_create and list_create_folder actions.
31.constant=PROJECT_CREATE_FOLDERS
Sample Code
Additional Resources
Preference Macros
The wt.prefs.WTPreferences class defines the following types of Preference
Context Macros:
• USER_CONTEXT - the context for individual users
• DEFAULT_CONTEXT - the context for the system default (shipping) values
• CONTAINER_CONTEXT - a context used in the container hierarchy
• CONTAINER_POLICY_CONTEXT - a container context that is enforced as a
policy
• DIVISION_CONTEXT - the context used for any scopes defined in addition
to the default, container, and user scopes
• DIVISION_POLICY_CONTEXT - a division context that is enforced as a
policy
Example:
PrefEntry~fileOperationType~ASK~/wt/content
Getting Preferences
You can get a preference by first navigating the preferences tree to the proper
node, then setting the context for that particular user, then getting the value for
that key.
Example:
// returns an instance of the top node in the Windchill preference
"tree"
Preferences root = WTPreferences.root();
// returns the preference node at that path
Preferences myPrefs = root.node( "/wt/content" );
((WTPreferences)myPrefs).setContextMask
(PreferenceHelper.createContextMask() );
// get( ), gets the value for that
// preference key
String prefValue = myPrefs.get( "fileOperationType", "SAVE" );
Preference Registry
The preference registry is a way to take a cryptic name like a preference and
provide a localized series of data about it. This registry is in the form of rbInfo
files. Anyone adding preferences to the system will have the option of adding this
localized information to the Preference Registry.
Where /node-name is the name of the node (for example /wt/workflow), /key-
name is the name of the key under the node (SortOrder) and % [ ]tag is one of the
tags mentioned above (% [ ]DISPLAY_NAME).
Creating a Preference
The creation of a preference is done through an XML load file. When creating a
preference the following pieces of information need to be determined:
• Unique preference name
<csvPreferenceCategory handler=
"wt.preference.LoadPreference.createPref
erenceCategory">
<csvname>CUSTOM_PREFERENCE_CATEGORY</csvname>
<csvparentName></csvparentName>
<csvdisplayName>
com.mycompany.pref.mycompanyPreferenceResource:
MyNewPreferenceCategory.displayName
</csvdisplayName>
<csvdescription>
com.mycompany.pref.mycompanyPreferenceResource:MyNewPreferenceCatego
ry.
description
</csvdescription>
</csvPreferenceCategory>
<csvPreferenceDefinition handler=
"wt.preference.LoadPreference.createPref
erence
Definition">
<csvname>/com/mycompany/MyNewPreference</csvname>
<csvvisibility>USER</csvvisibility>
<csvcategoryName>CUSTOM_PREFERENCE_CATEGORY</csvcategoryName>
<csvdisplayName>com.mycompany.pref.mycompanyPreferenceResource:MyNew
Preference.displayName</csvdisplayName>
<csvdescription>com.mycompany.pref.mycompanyPreferenceResource:MyNew
Preference.description</csvdescription>
<csvlongDescription>com.mycompany.pref.mycompanyPreferenceResource:
MyNewPreference.longDescription</csvlongDescription>
<csvdefaultValue>Default Value</csvdefaultValue>
<csvLinkPreferenceClientDefinition handler=
"wt.preference.LoadPreference.set
ClientDefinitionLink">
<csvname>/com/mycompany/MyNewPreference</csvname>
<csvclientName>WINDCHILL</csvclientName>
</csvLinkPreferenceClientDefinition>
</NmLoader>
5. Load the preference category and preference definition using the following
command:
windchill wt.load.LoadFromFile -d <full
path>/createMyNewPreference.xml
Deleting a Preference
The deletion of a preference is also done through the use of an XML load file.
Using the example from the Creating a Preference section on page 9–20, we will
delete the preference /com/mycompany/MyNewPreference. The deletion of the
preference will also remove any preference instances which may have been set for
this preference in the UI.
1. Create an XML file, deleteMyNewPreference.xml, containing the
following definition to specify the deletion of the preference.
<?xml version="1.0"?><!DOCTYPE NmLoader SYSTEM
"standardX10.dtd">
<NmLoader>
<csvDeletePreferenceDefinition
handler="wt.preference.LoadPreference.deletePreferenceDefinition">
<csvname>/com/mycompany/MyNewPreference</csvname>
</csvDeletePreferenceDefinition>
</NmLoader>
2. Delete the preference definition using the following command:
windchill wt.load.LoadFromFile -d <full
path>/deleteMyNewPreference.xml
Background
Offline packages exported from Windchill are zip files containing the exported
files. Along with the exported content, an offline viewer is provided which allows
users to browse the contents in their web browser.
By default, offline packages exported from Windchill display the Windchill logo
and brand in the header of the offline view. This document describes how to
update certain files on your installation server to have the exported packages
display your company’s brand identity.
Scope/Applicability/Assumptions
Utilizing this solution will change the format of all packages exported from the
server. It will affect all users and organizations that make packages from that
server.
Intended Outcome
The offline view in exported packages display updated brand identity information
for your company.
Solution
Update the CSS in the static resources zip file to style the header of the offline
view.
Solution Elements
Element Type Description
resources.zip Zip file This zip file contains the static elements
provided in the resources folder in every
package generated from the installation
server. This file is located in the <Windchill
>\codebase\com\ptc\netmarkets\wp\ixb
directory of your server.
wpofflinestyles.css CSS Style Contained within the resources.zip file, this
Sheet CSS style sheet contains the rules which
control the look and feel of the offline
view.
head.html HTML File The HTML file which is loaded at the top
of every page.
header.gif GIF graphics The background image of the header
file
logoWC.gif GIF graphics Transparent GIF of the Windchill logo.
file
Customization Points
CSS rule Default Value Description
.pageHeader Dark teal background Defines the border,
with Windchill background image and
background image color of the header.
(header.gif) and a dark
green bottom border.
.wncApplLogo logoWC.gif Defines logo graphics
file.
.applLogo Height: 55 pixels. Defines the height of the
logo div, normally shown
in the upper left corner of
the page.
.pageHeaderActions(CSS White text links. Defines the style of links
rule in wpofflinestyles. and text normally in the
css) upper right corner of the
page.
pageHeaderActions(div in Delivered empty Links can be added to this
head.html) div.
Limitations
Updating the resources.zip file in this manner affects every offline package
created by the system. It is not currently possible to apply these changes to one
package and not to another. Modification of packages after they are created is not
possible on the server.
Sample Code
.pageHeader {
border-bottom: 1px solid #20313d;
background-image: url(header.gif);
background-color: #40637A;
.wncApplLogo {
background-image: url(logoWC.gif);
}
.applLogo {
background-repeat: no-repeat;
height: 55px;
background-position:34px;}
<font face="verdana">
<!-- Banner begins here -->
Windchill server will be down 1/1 for maintenance
<!-- Banner ends here -->
</font>
</div>
Terminology
The following specialized terms are used in this section:
• Component Builder : A Java class used to “build” a UI component, i.e. a UI
widget. These builders define properties of your component to tell the
infrastructure how to display them.
• Status Family ID : A string used to reference a status glyph.
Solution
Developers can include status glyphs in their tables and information pages directly
from a ComponentBuilder class.
Prerequisite Knowledge
To achieve this goal, you need to have an understanding of the following:
• Java Programming
• General understanding of MVC builders
The OOTB glyphs can easily be included in an info page or table by using its
corresponding Status family id. The naming convention for these glyphs is:
statusFamily_<family name>
The following snippet shows how you can add a status glyph to the information
page for a particular business object type. In the builder for that business object
type, override the buildInfoConfig() method to add the glyph component
to the info page component. For example:
public static InfoConfig buildInfoConfig(InfoComponentConfigFactory
factory)
throws WTException {
InfoConfig infoConfig = factory.newInfoConfig();
...
PropertyConfig statusFamilySecurity = factory.newPropertyConfig
("statusFamily_Security");
statusFamilySecurity.setStatusGlyph(true);
infoConfig.addComponent(statusFamilySecurity);
...
return infoConfig;
}
The following snippet shows how you can add a status glyph to a table for a
particular business object type. In the builder for that table, override the
buildComponentConfig () method to add the glyph component to the table
component. For example:
public ComponentConfig buildComponentConfig(ComponentParams params)
throws WTException {
ComponentConfigFactory factory = getComponentConfigFactory();
TableConfig tableConfig = factory.newTableConfig();
...
ColumnConfig col1 = factory.newColumnConfig("statusFamily_Share", false);
tableConfig.addComponent(col1);
See Constructing and Rendering a Table Using the JSP Framework on page 564
for more information on tables.
Additional Resources
• Constructing and Rendering a Table Using the JSP Framework on page 564
• Icon Delegates on page 693
This chapter describes how to customize actions and add them to the user
interface.
473
Action Framework for Windchill Client
Architecture
The action framework for the Windchill client architecture supports the ability to
configure new actions and action models in the system.
This section describes the action framework for the Windchill Client Architecture.
It does not include information on how to control the display of the actions. For
more information on controlling the display, see Related Documentation section.
Prerequisite knowledge
• XML file structures
Related Documentation
• Constructing and Rendering a Table Using the JSP Framework on page 564
• Windchill Client Architecture Tree on page 599
• Information Pages on page 930
• Customization Tools Overview on page 381
• Customizing Product Family Matrix Editor
The action framework provides a way to define actions and action models within
the system:
• StandardNmActionService manages the set of actions and action
models in the system.
In general, as a developer, you would not directly make calls to the
StandardNmActionService. These calls are done through the
components that support action and action model display (for example tables,
trees, and information pages).
• Actions and action models are defined using the XML files referred to as
actions*.xml and actionmodels*.xml.
Caution
If you have a <model> element in the custom-actionmodels.xml file,
and a model by that name already exists, your model will completely override
the ones processed before your custom action models file. Be very careful in
the naming of your models so that you do not wipe out others from files read
in prior unless that is the intent.
objecttype Tag
The objecttype is a way to create a name space as well as packaging for
actions related to a specific object or functional area. In the above example, the
name “document” creates a unique name space for actions that apply to
wt.doc.WTDocuments.
Naming conventions for the name of an objecttype can be any combination of
alpha-numeric characters. Most objecttypes are an alias for the persistable
object to which the actions relate. Actions that apply to any object type, such as
copy, can be put within the objecttype of “object”.
Note
PTC recommends that all custom objecttypes have a prefix specific to the
company to prevent collisions with object types delivered with the product.
action Tag
The action name is a unique identifier for an action within the context of the
object type. The object type in conjunction with the action name make the action
unique within the system.
By default, the action name corresponds to the name of a JSP within the package
named for the object type. The packaging is relative to codebase/
netmarkets/jsp. For example, the action name in the XML example above is
“create.” Within the document object type, this corresponds to codebase/
netmarkets/jsp/document/create.jsp.
Naming conventions for the name of an action can be any combination of alpha-
numeric characters.
Note
PTC recommends that all your custom actions have a prefix specific to your
company to prevent collisions with names of actions delivered with the
product.
Command Parameters
Pa- De- Po- Re- Description
ra- fau- ssi- q?
me- lt ble
ter Val- Val-
ue ues
class No The class to use for processing.
met- No The method in the class to execute.
hod
Note
The use of the HTML-encoded character "'" to use a
single quote is not necessary; just use a regular
single quote instead.
Note
The use of the HTML-encoded character "'" to use a
single quote is not necessary; just use a regular
single quote instead.
When the actions are parsed, the action framework tries
to repair troublesome definitions. If they cannot be
repaired, then the onClick function is replaced with
an alert. Warnings are logged if the action was repaired;
otherwise errors are logged.
If the selectRequired attribute is set on the action,
then the onClick handler is called before any other
handlers. Thus, the onClick handler must check if
there are items selected in the table.
Note
Supported and non-supported types can also be added using xconf properties
See Defining Supported and NonSupport Types in XConf for more
information.
For example:
<Property name="annotation.annotationSets.nonSupportedTypes"
value="wt.part.WTPart" target="codebase/
typeBasedActionFilter.properties"/>
The objecttype name is a way to create a name space as well as packaging for
actions related to a specific object or functional area. In the above example, the
name “document” creates a unique name space for actions that apply to
wt.doc.WTDocument.
It is also possible to create an action model which itself references another action
model. The folder browser Actions menu contains a submodel for the New group
of actions. For example, the action model for the New group of actions might be
defined as follows:
<model name="folder_file_new" resourceBundle="com.ptc.core.ui.tableRB">
<action name="create" type="document" resourceBundle=
"com.ptc.core.ui.tableRB" />
<!-- More actions here --!>
</model>
Then, in the action model for the Actions menu, include the submodel “folder_
file_new”:
<model name="folder_file">
<submodel name="folder_file_new"/>
<action name="create" type="document"/>
<!-- More actions here --!>
See the figure below for how this appears in the user interface:
Model Attributes
Details about these parameters can also be found in the codebase/config/
actions/actionsmodels.dtd.
Pa- Default Possi- R- Description
rame- Value ble e-
ter values q?
name Y- This is the name by which the action model is
es referenced
menu- Any No Specifies which action should be highlighted
for valid by default. This is only applicable if the
class model is used as a third-level navigation
name. menu.
de- First Action Specifies which action should be highlighted
faul- action in name for by default. This is only applicable if the
tAc- the model one of model is used as a third-level navigation
tion- is used the menu.
Name by actions in
default the
model.
Action Attributes
Details about these parameters can also be found in codebase/config/
actions/actionsmodels.dtd.
Pa- De- Possible Req? Description
ra- fault Values
me- Value
ter
na- Name of Yes This is the name of an action defined in an
me any actions.xml file
action
defined in
an
ac
tions.x
ml file
type Name of Yes This is the name of an object type defined
any in an actions.xml file.
object
type
defined in
an
aac
tions.x
ml file
sho- true No This determines whether an action is
rtc- false displayed as a shortcut icon in the toolbar.
ut
Note
The action service is designed to hide the icons in the actions menu (or menu
bar menus) for any icon which is not contained in a toolbar somewhere else in
the system. The StandardNmActionService builds and keeps a list of
all known toolbar icons on server startup.
The StandardNmActionService is relying on the name of the model to
know whether it is a toolbar. Therefore, the name of a model used as a toolbar
should contain “toolbar.”
If the toolbar model naming convention is not followed, then the action
service cannot show icons as designed. However, no functionality breaks if the
naming convention is not followed.
"
Commonly used shortcut actions (recommended maximum up to five) can be
configured to appear on a toolbar shortcut area using a shortcut attribute.
Example configuration for folder browser table:
<model name="folder_list_toolbar">
………………………………………..
<action name="CONTAINERMOVE"
type="pdmObject" shortcut = "true"/>
<action name="PAGERELOADINGMULTICHECKOUT"
type="folder" shortcut = "true"/>
<action name="WFADDTOWORKSPACE"
type="folder" shortcut = "true"/>
…………………………….
<action name="create"
type="folder" shortcut = "true"/>
<action name="create"
type="document" shortcut = "true"/>
…………………………………
</model>
An action is a shortcut action only in the context of that specific model. Note that
icons for actions in the menus are be displayed for actions that also display in the
toolbar.
Sample Code
The following is sample code for an action model that configures a subtype:
<!-- Copied from ChangeManagement-actionModels.xml -->
<!-- Originally copied from menu for wt.change2.WTChangeRequest2 -->
<model name="sample change request actions" menufor="WCTYPE|
wt.change2.WTChangeRequest2|org.default.www.SampleChangeRequest">
<action name="view" type="object"/>
<action name="SETLIFECYCLESTATE" type="pdmObject"/>
<action name="createSubscription" type="subscription"/>
<action name="separator" type="separator"/>
<action name="reviseChangeItems" type="change"/>
<action name="editCapabilityPackage" type="capabilityPackage"/
>
<action name="create" type="approach" />
<action name="create" type=
"capabilityImplementationProject" />
<action name="separator" type="separator"/>
<action name="sandboxAddToProject" type="object"/>
<action name="SBAddToPrj" type="sandbox"/>
<action name="removeShare" type="object"/>
<action name="separator" type="separator"/>
<action name="ManageSecurity" type="accessPermission"/>
<action name="renameObjectWizard" type="object"/>
<action name="delete" type="object"/>
<action name="separator" type="separator"/>
<action name="separator" type="separator"/>
<action name="discuss" type="forum"/>
<action name="copy" type="object"/>
Localize Actions
The format for entries in the .rbInfo is:
<objecttype name>.<action name>.<purpose>.value=<value>
For example:
<objecttype name="document" class="wt.doc.WTDocument"
resourceBundle="com.ptc.windchill.enterprise.doc.documentResource">
<action name="create" uicomponent="CREATE_DOC" dtiUpload="true">
<command
class="com.ptc.windchill.enterprise.doc.forms.CreateDocFormProcessor"
method="execute" windowType="popup"
onClick="validateCreateLocation(event)"/>
<includeFilter name="projectM4D" />
</action>
</objecttype>
Icon and tooltip are shown here in the toolbar and also in the menus. Note that
icons for actions in the menus are only displayed for actions that also display in
the toolbar:
document.create.title.value=New Document
Title:
The <U class="mnemonic > </U> tag should be put around the character that
is the access key (“R” in the example above).
Action Report
http://<your machine name>/<app-name>/app/#ptc1/
carambola/tools/actionReport/action
The Action Report allows you to search for actions managed by the
StandardNmActionService. You can search by several properties for the action
including the label (the description), action name, and object type name.
The search supports multiple search parameters, regular expressions, and case-
insensitive matching. See Action Report on page 383 for more information.
Debug Tool
There is also a debug mode that can be enabled in the user interface to find
information about a particular action on a page. See Debugging on page 381 for
information on enabling and using this tool.
Reload Actions
http://<your machine name>/<app-name>/app/#ptc1/
carambola/tools/list
This tool reloads the action models from their XML files without having to restart
the method server. See Reload Action on page 381 for more information.
Tab Models
Objective
You want to change something in the navigator section of the page. For example,
you want to add or remove tabs in the navigator.
Background
The tabs rendered in navigator are nothing but actions in action lists just like any
other actions in the system. Adding tabs and tabs under them is very much like
adding any other action into the system, but there are some additional special
considerations.
Scope/Applicability/Assumptions
• Assume you need to add a new tab to the main navigation of the navigator.
• Assume you need to remove an existing tab from the main navigation of the
navigator.
• Assume you need to add/remove links in the second level navigation.
Solution
Create new actions, an action model, and JSPs for the tab and sub tabs to be
added.
Solution Elements
Element Type Description
codebase\config\actions XML This file contains the action
\navigation-actions.xml definitions for the actions that
represent the tabs and sub tabs
in the Windchill system
codebase\config\actions XML This file is used for adding
\custom-actions.xml custom actions and customizing
existing actions.
codebase\config\actions XML This file contains the action
\navigation-actionModels.xml model definitions used in the
navigation. Including the main
tab list, the sub tab list, the
recent lists, and the header
actions lists.
codebase\config\actions XML This file is used for adding
\custom-actionModels.xml custom action models and
updating existing action models.
Note
Custom second level navigation links can be added only on the Browse tab.
They are not supported on Search tab or any custom tabs.
Customization Points
See Action Framework for Windchill Client Architecture on page 474 for more
information.
There are also other methods that you may wish to override but
getRecentStack() is the only one required for this particular use case.
Register MyTabNavigationListDelegate
To register this custom delegate, the property should be added to a specific
customized service.properties.xconf file or site.xconf.
In the above example you would register it something like the following:
<Service name="com.ptc.jca.navigation.NavigationListDelegate">
<Option serviceClass=
"com.ptc.myTab.navigation.MyTabNavigationListDelegate"
requestor="java.lang.Object" selector="MyTab"/>
</Service>
After registering you will need to run xconfmanager -p from a windchill shell
and restart the method server.
The sub-model can be nested into other submodel to add multiple levels of
navigation
Example:
The above model can have more submodels as
<model name="productNav1">
<action name="info" type="product"/>
<action name="listFiles" type="product"/>
<submodel name="productNav2" />
</model>
Where
<model name="productNav2">
<action name="someAction" type="object"/>
<action name="someMoreAction" type="object"/>
….
</model>
Additional Resources
• Action Framework for Windchill Client Architecture on page 474.
Background
The role-based UI functionality enables administrators to optimize the number of
actions presented to users, so as not to confuse users by seeing actions they don't
need or use for their role. Initially this support was just for container managers (in
particular, project managers). It has been extended to a concept called profiles
which sets action visibility at the site or organization level.
A site administrator, organization administrator or container administrator can
specify which users have visibility to the actions defined. For site and organization
administrators, this can be done through profiles. Profiles can be created at Site-
>Profiles or Org->Profiles. The actions defined are presented with their default
settings, and the administrator can choose to hide those actions. The administrator
can then specify which participants (users, groups, orgs) belong to the profile. All
members of the profile have that visibility. If a member is in multiple profiles, the
greatest visibility is provided.
Scope/Applicability/Assumptions
• The role-based visibility administration capability is turned on, that is, the
preference com.ptc.netmarkets.roleAccess.enabled is set to true. The
customization can be performed while the capability is turned off, but the
results do not appear in the UI until the capability is turned on.
• The customizer can manage both out-of-the-box UI components and
customized UI components with this capability.
Intended Outcome
When configuring visibility by roles and configuring profiles, the administrator is
presented with a list of UI components that can be managed. The administrator is
unable to manage the visibility for any UI components that are not included in this
list.
As a customizer, you have the ability to customize the list of UI components
available to administrators. You can:
• Add UI components to the list,
• Remove UI components from the list,
• Specify default visibility settings for UI components,
• Change the order that UI components appear in the list, and
• Change the labels for the UI components on the list.
Solution
Modify the roleaccessprefs.xml file (and associated files as needed).
Solution Elements
Element Type Description
*actions.xml XML Files where actions and other UI
components are defined. Actions are
optionally given a uicomponent value.
Actions.xml is located in <Windchill
>/codebase/config/actions along with
other *actions.xml files.
Roleaccessprefs.xml XML File for assigning default visibility to
UI components. Setting items in this
file can make them not appear at all for
the site or containers. Whether or not
the container manager can override the
default value can also be changed here.
Located in <Windchill>/codebase.
RoleAccessResource.java java Defines the labels to provide in the Uis
for the actions or UI components.
Located in <Windchill>/src/com/ptc/
netmar kets/roleAccess/.
In actions.xml (and all *actions.xml files), an action can be assigned a
uicomponent attribute value. The uicomponent attribute provides a name for a UI
component that can be referenced from the roleaccessprefs.xml and
roleAccessResource.java files. Multiple actions can use the same uicomponent
value; this provides the ability to manage those actions as a single UI component.
If an action does not have a uicomponent, then the action “name” can be used to
reference it as a UI component instead. However, in this case it cannot be grouped
with other actions into a single UI component.
The roleaccessprefs.xml file consists of a <uics> element containing several
elements (or sections) that correspond to the primary tabs in the Windchill user
interface. For example, the <project> section corresponds to the Project tab. Each
section contains zero or more <uic> elements, each representing a UI component
Note
Your UI component label should be a verb phrase. If your action/UI
component name is not already a verb phrase, place 'View' in front, for
example "View Team Page."
Note
This example assumes that the Create Folders action is not already available
for role-based visibility management; in the actual product, it is available out
of the box.
Note
For actions that are valid for multiple tab types, put the entry under all the
section you want it to affect.
Caution
Follow best practices in backing up your XML files when customizing
them.
As a result, the "Create Folders" entry in the Configure Actions for Roles and New
Profile pages affects the visibility for both folder_create and list_create_folder
actions.
runClass="com.ptc.netmarkets.roleAccess.StandardNmRoleAccessService"
runMethod="modifyTeamPermissions"/>
The principal passed in is the group or user on which to operate. The boolean
isRender is what the field in the UIAccess table was just set to for the passed in
principal.
Sample Code
Examples of Usage in out-of-the-box Code
An example of multiple actions using the same uicomponent is the Team pages in
Product/Project/Library share the same code, but each action is defined separately
for each object. Each action has the same uicomponent of "PROJECT_TEAM".
This allows the same resource entry to be used, and helps to minimize the size of
the action display table in the New Profile page. PROJECT_TEAM still needs to
be defined in roleaccessprefs.xml for each tab type in which it is used, and
different defaults can be set for each.
Additional Resources
Related Customization Documentation
• Managing Customizations on page 109.
Background
As a user navigates within Windchill, they may make changes that affect the user
interface display, such as selecting a tab on the information page (for example,
selecting My Tab). If the browser is refreshed, the user may expect to remain on
their last active tab. To retain this information, some sort of persistence
mechanism is required to refresh the page to the correct state .
There are two persistence mechanisms available for use. The Client State Provider
will store information in the browser and will be specific to that particular browser
on that particular machine. The Server State Provider will store information in the
database and will make the information available for that user on any browser and
any machine.
Resetting Stickiness
If user interface stickiness is causing issues or acting strangely, you may need to
reset the stickiness. Server state stickiness and client state stickiness are reset
differently, and you don’t necessarily need to reset both, depending on what is
acting strangely.
To reset the server state stickiness, navigate to http://<host>/<webapp>/
app/netmarkets/jsp/user/utilitiesList.jsp and click “Reset
Server Stickiness”. This action will popup a confirmation box and by clicking OK
all your server state stickiness will be reset to the default state. This includes both
Information Page tab order and Information Page table order.
Various actions may clear the client state provider stickiness information
depending upon your browser. To ensure that all client stickiness is removed,
delete all your temporary internet files (usually in the Tools menu), close all
browser windows, and restart the browser.
Background
There are several documents that describe certain aspects of the Action Model
framework. This documentation is intended to provide concrete examples for a
few of the main uses of action models within the Windchill application.
Scope/Applicability/Assumptions
This documentation is intended to be used as a starting point for developers
wanting to configure an actions menu to be rendered in the UI using the JCA
framework. This information has references to other sources of information which
will cover specific topics in greater detail.
Intended Outcome
The following sections provide a screenshot for the main areas where action
models are used.
Displaying Actions
You want to have a set of actions be displayed in one of the following areas:
• Actions column in a table
• Toolbar actions for a table
• Menu bar actions for a table
• Actions menu on an information page
Note
You can no longer add the actions column to tables. The actions column is in
the data store, but not available in the UI. The actions menu is only available
by right-clicking each row
<model name="submenu_new">
<action name="newViewVersion" type="part"/>
</model>
b. Set action model in a Builder.
There can only be one action model per type with the menufor attribute. If
you would like to override the default action model for your table you can
specify a different model in your table builder. See MVC Components on
page 247 for information on creating a table builder class.
public ComponentConfig buildComponentConfig (ComponentParams
params) {
ComponentConfigFactory factory = getComponentConfigFactory ();
JcaTableConfig table = (JcaTableConfig) factory.newTableConfig ();
(JcaColumnConfig)actionsMenu).setDescriptorProperty
(DescriptorConstants.ActionProperties.ACTION_MODEL,
"model_name_here");
table.addComponent(actionsMenu);
....
return table;
}
@Override
public Object getDataValue(String component_id, Object datum,
ModelContext mc) throws WTException {
String modelName = "foo";
if(...) {
modelName = "bar";
} else {
modelName = "baz";
}
mc.getDescriptor().setProperty( DescriptorConstants.
ActionProperties.ACTION_MODEL, modelName);
return super.getDataValue(component_id, datum, mc);
}
}
You can specify different action models for different types of datums (row
objects) or use other logic based on information in the model context to
determine the action model to use.
After creating your data utility, add a column to the table in the builder.
Use a custom column id (i.e “customNmActions”) instead of
DescriptorConstants.ColumnIdentifiers.NM_ACTIONS:
public ComponentConfig buildComponentConfig (ComponentParams
params) {
ComponentConfigFactory factory = getComponentConfigFactory ();
JcaTableConfig table = (JcaTableConfig) factory.newTableConfig ();
....
table.addComponent(actionsMenu);
....
return table;
}
Finally, you’ll need to register your data utility for the custom column id in
an *.xconf entry, e.g:
<!-- Sample XCONF Entry -->
<Service name="com.ptc.core.components.descriptor.DataUtility">
<Option serviceClass="com.ptc.windchill.dataUtilities.
CustomNmActionDataUtility" requestor="java.lang.Object"
selector="customNmActions" cardinality="singleton"/></Service>
Trouble Shooting
Problem Solution
Description
Action Column does By default, the actions column is not displayed. Users are
not appear in Table not allowed to see it. Right-clicking a row is the only way
to see the row actions.
Icons for some To follow UI standards, the action service is designed to
actions are missing only show the icons in the actions menu if those icons
table.addComponent (factory.newColumnConfig
(DescriptorConstants.ColumnIdentifiers.NM_
ACTIONS
, true));
....
return table;
}
Wrong set of actions Add jcaDebug=true and check what vaildators are on the
is showing. actions in the menu. Check that the validators are working
as you’d expect.
1. If you expect the action model to be found by type
(described in the Actions Column in a Table section
under Intended Outcome on page 523) , is ‘menuFor’
defined on the action model for the object type?
To see what the action service is finding for the type
of object in the row, turn on log4j logger :
com.ptc.netmarkets.util.misc.
StandardNmActionService
2. If the model to use is defined on the table/column
(described in the Actions Column in a Table section
under Intended Outcome on page 523):
To see what action model the default data utility is
returning turn on log4j logger: com.ptc.core.
components.factory.dataUtilities.
NmActionDataUtility
The jcaDebug param will also produce a link to the
action model report at the bottom of the menu. The
action model report will have the model name, the set
of actions in that model, where the model is defined,
whether the model overrides any other models, etc.
Make sure the model is defined as you’d expect.
<!-- Menu Bar Action Model for the Folders table -->
<model name="folders table menubar">
<submodel name="folder file menu"/>
<submodel name="folder edit menu"/>
…
</model>
<!-- File Menu Action Model for the Folders table -->
<model name=" folder file menu">
<submodel name="submenu file new"/>
<action name="action1" type="folder"/>
…
</model>
<!-- Edit Menu Action Model for the Folders table -->
<model name=" folder edit menu">
<action name="copy" type="Object"/>
<action name="paste" type="Object"/>
…
</model>
Trouble Shooting
Problem Description Solution
Icons for some actions are missing Only the actions that are displayed in a
table toolbar have icons in the actions
menu.
Some actions don’t appear in the list in There may be a validator configured on
the UI it which may hide the action in certain
conditions. See Action Framework for
Windchill Client Architecture on page
474 for information on configuring an
action with a validator.
Add jcaDebug=true to the url to see
even the hidden actions. With the
jcaDebug option enabled, you’ll see
more information in the menu, and
there will be an action at the end of the
list that takes you to the action model
report for that menu.
To get a menu to fly out from the main menu, add a submenu to the action
model.
<model name="submenu_new">
<action name="newViewVersion" type="part"/>
</model>
return infoConfig;
}
Note
Your builder should extend DefaultInfoComponentBuilder or
AbstractInfoComponentBuilder.
Trouble Shooting
Problem Description Solution
Icons for some actions are missing Only the actions that are displayed in a
table toolbar have icons in the actions
menu.
Some actions don’t appear in the list in There may be a validator configured on
the UI it which may hide the action in certain
conditions. See Action Framework for
Windchill Client Architecture on page
474 for information on configuring an
action with a validator.
Add jcaDebug=true to the url to see
even the hidden actions. With the
jcaDebug option enabled, you’ll see
more information in the menu, and
there will be an action at the end of the
list that takes you to the action model
report for that menu.
Intended Outcome
This documentation describes the process for adding a custom option to the
customize list on the Home page. This new item appears in the customize action
on the Home page and when selected its content renders in the page along with the
selected out of the box components.
Prerequisite Knowledge
To achieve the intended result you need to have an understanding of the following:
• Action Framework for Windchill Client Architecture on page 474
Defining Menus on page 523
Solution Elements
The default out of the box action model is:
<model name="home customization">
<description>Used for the customization options on the
homepage</description>
<action name="listAssignments" type="work"/>
<action name="listUpdates" type="report"/>
<action name="listCheckedOutWork" type="user"/>
<action name="homeList" type="wp"/>
<action name="MyWorkspace" type="workspaces"/>
<action name="list_mine" type="meeting"/>
<action name="userNotebook" type="user"/>
<action name="listSubscriptions" type="subscription"/>
<action name="reports" type="user"/>
<action name="savedReports" type="user"/>
Note
This is a simple example action that ignores localization.
3. Add the action to the custom copy of the home page action model in
custom-actionmodels.xml.
<model name="home customization">
<description>Used for the customization options on the
homepage</description>
<action name="listAssignments" type="work"/>
<action name="listUpdates" type="report"/>
<action name="listCheckedOutWork" type="user"/>
<action name="homeList" type="wp"/>
<action name="MyWorkspace" type="workspaces"/>
<action name="list_mine" type="meeting"/>
<action name="userNotebook" type="user"/>
<action name="listSubscriptions" type="subscription"/>
<action name="reports" type="user"/>
<action name="savedReports" type="user"/>
<action name="dataMonitors" type="user"/>
<action name="assignedClashesNav" type="clashReport"/>
<action name="participationView" type="forumTopic"/>
<action name="actionGroup" type="user"/>
<action name="customHomePageAction" type="myCompany"/>
</model>
Limitations
Only components for which an action can be created can be added to the Home
page. This is not very limiting as most things can be wrapped in a JSP.
This chapter describes how to gather data to be used in the user interface.
543
Acquiring Data via Info*Engine
Objective
You want to use an Info*Engine task to get the data for a Windchill Client
Architecture table component.
Background
The Windchill Client Architecture provides IeTaskInfo to be returned from its
ComponentDataBuilder for retrieving data using the Info*Engine task. Its
action maps to an Info*Engine task, which will be executed to get the data for the
component.
Intended Outcome
A Windchill Client Architecture table that has its data populated by an
Info*Engine task.
Solution
Return an IeTaskInfo from a Windchill Client Architecture table’s component
data builder.
Prerequisite Knowledge
Readers should be familiar with Info*Engine as well as with the basic Windchill
Client Architecture data acquisition concepts.
Solution Elements
Element Type Description
ComponentDataBuilder Java interface Creates the
data model for
the component
IeTaskInfo Java class Encapsulates
information
about the
Info*Engine
task and the
parameters that
can be passed
to the task
@Override
public Object buildComponentData(ComponentConfig config,
ComponentParams params) throws WTException {
Limitations
None.
Sample Code
Look for the builder examples available in carambola
• com.ptc.mvc.builders.carambola.table.MvcTableBuilderWithIETask
Related Documentation
• Info*Engine User’s Guide
• Windchill Adapter (Info*Engine)
Background
Each attribute panel and each row in a JCA table or tree has a datum object from
which the data for the attribute or table cell values is extracted and the object
identifier for row actions and for row selections is obtained. The datum object is
provided by the buildComponent() method of a Java builder class or by a
getModel() or getIEModel() JSP tag. Datum objects are typically
Persistable objects or, in the case of create and edit wizards, TypeInstances
representing Persistable objects. However, other types of Java objects (for
example, a HashMap) can be used.
Solution
When the value of an attribute should be extracted from an object other than the
datum object you can configure a different “target object” from which attribute
values should be obtained.
The target object will be passed as the “datum” to data utilities instead of the
datum object. Note that the specified target object must be addressable from the
datum object. See Procedure – Configure a different target object
In cases where the datum object for a table or tree is not a Persistable object
whose identifier can be used for table row actions or row selection you can
configure how the row object identifier should be obtained. In order of preference,
your options are:
• Procedure – Implement getOid() on your row data object
• Procedure – Configure a diferent target object
Prerequisite Knowledge
You need to have an understanding of the following:
• Windchill application context (“service.properties”)
• JCA Overview
• MVC Overview
• JCA NmObjects Overview
Related Information on page 555 includes references to many or all of these
subjects.
Limitations
The infrastructure will try to get a target object for every row even if you do not
need one. There is no way to tell the infrastructure not to do this.
If you do not have your table configured correctly you may see an error like
2011-02-24 16:42:10,883 TRACE [TP-Processor7]
com.ptc.core.components.factory.dataUtilities.DefaultN
mObjectUtility wcadmin - nmObject
2011-02-24 16:42:10,883 DEBUG [TP-Processor7]
com.ptc.core.components.factory.dataUtilities.DefaultN
mObjectUtility wcadmin - Exception occured trying to get an
oid property.
java.lang.NoSuchMethodException: Unknown property 'oid'
on class 'class
com.ptc.core.meta.type.common.impl.DefaultTypeInstance'
...
Related Information
• Windchill Client Architecture Overview on page 223
• Windchill Client Architecture Common Objects Overview on page 236
• MVC Components on page 247
Scope/Applicability/Assumptions
You have one of the following:
• JavaScript code
• A JSP page or fragment
• A Java class that descends from DefaultObjectFormProcessor, or
another use of a FormResult object
The code needs to allow a user to download a file, identifiable by a URL, to the
user’s computer. The download must not interfere with any pending AJAX
transaction, and must run in the background without preempting the Windchill UI.
For example, you might have a wizard that guides a user to select a document, and
a class <MyWizardFormProcessor>.java to process the form on closure. The form
processor can return a FormResult with the next action set to
FormResultAction.JAVASCRIPT, that includes a JavaScript call to
download the selected file.
Intended Outcome
The user’s web browser will present its standard file-save dialog box:
Prerequisite Knowledge
To achieve this result, you need to understand:
• Basic development of Windchill web pages
• JavaScript
• Web server configuration and content-disposition
• URL security best practices
Customization Points
Parame- Default Possible Values Re- Description
ter Value quired
url None • A full URL Yes The URL of the
(protocol:// file to be
credentials@ downloaded to the
server/path1/ client.
path2…)
• A root-relative
URL (/path1/
path2…)
• The current
Windchill root
(from
getBaseH
ref()) will be
prepended to the
parameter.
• A current location-
relative URL
(path1/
path2…)
Limitations
This practice is limited to content types that web browsers cannot display. It
cannot be used for text, HTML, XML, or common image formats such as PNG,
JPEG, or GIF.
Packaged Samples
There is an example that illustrates use of the downloadURL function in a
wizard. If you have the Client Customization utility enabled navigate to Navigator
▶ Customization ▶ Test Clients ▶ Download File Example to see the example.
The Client Customization utility is not enabled by default. See Enable
Customization Utilities on page 381 for instructions on how to enable the utility.
This chapter describes how to customize information that is displayed in the user
interface.
Background
The table common component presents information in a tabular format to help
users scan, locate, compare, and take actions on related data. Users may control
how to view data in the table using sorting and views.
Scope/Applicability/Assumptions
Table common component should be used when there is a requirement to display
Windchill business objects in tabular form and not just for displaying the HTML
Table.
Solution
Implement MVC table builders to create or convert a JCA table component.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following JCA
techniques:
• Data utilities
• GUI component
• Actions framework
• Configurable table views
• Java annotations
Solution Elements
Element Type Description
ComponentData- Java interface Creates the data model for the
Builder component
ComponentConfig- Java interface Creates the configuration for the
Builder component
ConfigurableTable- Java interface Creates the configurable table views
Builder for tables and trees
AbstractConfigura- Java class Base class that builders typically
bleTableBuilder extend
If you wish to configure separate builders without using annotations, then the bean
ids you choose must have the “.configBuilder” or “.dataBuilder” suffix. For
example to configure a config builder, you would do the following:
<bean name=”myComponent.configBuilder”
class=”my.config.builder.class.name”/>
Overview
This section describes the mapping of attributes from the 9.x legacy tags to the
corresponding attributes on the new MVC table builders.
@Override
public ComponentConfig buildComponentConfig(ComponentParams params) {
ComponentConfigFacory factory = getComponentConfigFactory();
TableConfig table = factory.newTableConfig();
table.setLabel(ClientMessage.get(RESOURCE,"PROJECT_LIST_NAME");
table.setType("wt.projmgmt.admin.Project2");
…
return table;
}
describeColumn
The content of the describeColumn tag is also specified in the
buildComponentConfig method of ComponentConfigBuilder interface. As the
column component is an child component of the table component, it is added to
the table config.
JSP code was like this:
<describeTable var="tableDescriptor" type="wt.part.WTPart"
id=" test.table" label="testTable" >
<describeColumn id="name" sortable=”true”/>
<describeColumn id="number"/>
</describeTable>
getModel
The content of the getModel tag is specified in the buildComponentData method
of ComponentDataBuilder interface.
JSP code was like this:
<jca:getModel var="tableModel" descriptor="${tableDescriptor}"
serviceName="com.ptc.netmarkets.projmgmt.ProjectCommands"
methodName="getProjects" ……. >
<jca:addServiceArgument value="${user}" type="wt.org.WTUser"/>
<jca:addServiceArgument value="${pseudoType}" type=
"java.lang.Integer"/>
</jca:getModel>
Customization Points
JcaTableConfig class APIs can be explored for various table level customization
points. JcaColumnConfig class APIs can be explored for various table column
level customization points.
@Override
public ComponentConfig buildComponentConfig(ComponentParams params)
throws WTException{
…
}
@Override
Sorting Behavior
• Table is sorted at client side in following scenarios:
1. It is an asynchronous datasource enabled table and application team has
not specified ‘preSorted’ property in result processor from builder to true.
2. If user explicitly changes the sort criteria and user revisits the table. (Sort
stickiness).
• Table is not sorted at client side in following scenarios:
1. If the application team set ‘preSorted’ property to true on the result
processor of table builder.
2. In case of synchronous datasource enabled table.
• During client side sorting, when the data chunk come to the client, they are
added to the store as per the client sort criteria.
• If the user clicks sort while the data is loading, the data gets sorted at client
side. Also the data chunks that come later are also added in sorted order.
• Multi-column sorting: Multiclick to sort feature allows the user to sort
multiple columns at a time there by pressing the shift key and then sorting.
The limitation is maximum three columns are allowed to sort at a time.
• In case of sorting on version column, sorting happens at server side.
The following configuration points are available for specifying which row(s) will
be struckthrough.
Adding a Toolbar
In order to add a toolbar, the key attribute must be set to “actionModel” and the
value attribute must be set to the name of the action model that contains the
toolbar actions.
For example:
TableConfig table = factory.newTableConfig();
table.setActionModel("customToolbar");
Configuring above action will produce an toolbar action model displayed as:
In order to label each menu, the description must be set for the File and Edit
submodels
The action properties must be included in either the action.properties file or in a
resource bundle
The properties depicted below are the entries that get added to the action.
properties file
The entries for the File and Edit actionModels would look like:
object.fileMenu.description.value=File
object.editMenu.description.value=Edit
If your table/tree is still defined in a jsp instead of with a builder, adding the help
topic would be as follows:
<renderTable model="${tableModel}" helpContext=" HelpTopicName"/>
}
…
}
The Attributes table in the Create Multiple Documents wizard, and the
Attachments table in the Attachments wizard step found in many wizards (new
Document, new Change Request, for example) have been configured to turn off
grid features because they contain a file input field in an editable table.
Limitations
None.
Other Resources
Related Customization Documentation
• Adding Actions and Hooking Them Up in the UI on page 473
• Customizing the UI with Ajax on page 277
• MVC Components on page 247
• Action Framework for Windchill Client Architecture on page 474
• User Interface Stickiness on page 522
Related Websites
The Spring Framework: http://www.springframework.org
Sample Code
Examples of Usage in Windchill Code
• Product > Folders table
• Product > Templates table
• Recent Updates table on Home page.
• Organization > Profiles table.
Note
If the customization source code examples are not installed on your server,
they are available for download from the following location: http://www.ptc.
com/view?im_dbkey=156765
Note
If the customization source code examples are not installed on your server,
they are available for download from the following location: http://www.ptc.
com/view?im_dbkey=156765
• Select “Table” for table that uses default OOTB result processor.
• Select “Table - Async” for table that uses a custom result processor.
Note
If the customization source code examples are not installed on your server,
they are available for download from the following location: http://www.ptc.
com/view?im_dbkey=156765
Example — Table(Info*Engine)
This is an example of MVC table implementation that use Info*Engine tasks as
the source of data. This is a synchronous data source example.
Note
If the customization source code examples are not installed on your server,
they are available for download from the following location: http://www.ptc.
com/view?im_dbkey=156765
Note
If the customization source code examples are not installed on your server,
they are available for download from the following location: http://www.ptc.
com/view?im_dbkey=156765
• Select “Table (Info*Engine)” for table using asynchronous data source mode.
• Select “Table (Info*Engine) - Async” for table using asynchronous data source
mode with configurable views.
Note
If the customization source code examples are not installed on your server,
they are available for download from the following location: http://www.ptc.
com/view?im_dbkey=156765
Background
A tree view is used to display hierarchical data organized in the form of a tree. In
other words, a Tree is a visualization of a hierarchy. In a tree structure, there are
parent and child nodes. The hierarchy level is shown by indentation on the left
side of the Tree nodes.
Implementing a Windchill Client Architecture tree is the same as implementing a
Windchill Client Architecture table. In tree, as opposed to specifying a service
method or QuerySpec, a TreeHandler is specified to populate the content.
Expand/Collapse Behavior
The expand/collapse functionality is used to traverse the hierarchy of the tree.
Your expansion of the tree will be sticky within a session and will return to the
default between sessions. You can expand or collapse a tree in two ways:
• By using the “Expand” and “Collapse” actions in the menu or toolbar.
○ Expand action enlarged to show detail
The expand icon will populate its next level children, where as the
Collapse icon merely changes the node from an open to a closed state.
Scrolling Behavior
You will loose your sense of the structure if the tree is divided among pages and
hence paging is inappropriate for trees. If there is large data to be presented, the
tree can be made to scroll with column header remaining static.
Sorting Behavior
Columns in a tree will sort similarly to tables with the following exception: as the
structure of the tree must remain intact – the sorting will occur level-by-level. For
example, in a folder tree when sorting alphabetically by name, first level folders
are sorted as a group, then objects in individual folders are sort as a group, and so
on.
Solution
Use Windchill Client Architecture Tree to display Windchill business objects in
Tree format.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• The actions framework in the Windchill client architecture.
• JCA Table component
• Data acquisitions, Data Utility, GUI component.
• JSP, JavaScript and Custom taglibs.
• Java annotations
It Fetches children for each node.The first call to this method from infrastructure
will always pass first argument as TreeNode.RootNode.This first call ensures that
all rootNodes are fetched for subsequent calls. The subsequent calls will always
pass a treeNode for which child nodes are required to be fetched.
E.g. The code should handle this case similar to following code snippet:
List nodes;
if (node == TreeNode.RootNode){
nodes = getRootNodes();
resultProcessor.addElements(nodes);
}else {
getNodes(node);
nodes = resultProcessor.addElements(nodes);
}
NmCommandBean cb = getModelContext().getNmCommandBean();
WTPart part;
if (part == null) {
log.debug("Couldn't get part");
return null;
}
configSpec = ConfigHelper.service.getConfigSpecFor(part);
return Collections.singletonList(part);
}
The method first retrieves the NmCommandBean from the model context and
extracts the primary oid from it. If no oid was requested from the user, then it uses
the GOLF_CART part instead by calling the getGolfCart method. The
getGolfCart method simply queries and returns the GOLF_CART. If the user did
specify an oid in the request parameter, it checks to make sure the oid is a
WTPart. Otherwise, it throws a ClassCastException. If it’s the expected oid, it
continues by retrieving the part from the oid via the getRef method. This method
inflates the referenced object, which then can be cast into a WTPart. The last thing
it checks is if the part retrieved either from the oid or the GOLF_CART is null and
if so return null. The configSpec variable is assigned the ConfigSpec of the part
using the ConfigHelper class. This helper class contains a service that helps obtain
Iterated objects from Mastered objects. Lastly, an immutable List containing the
part is returned.
getNodes(List parents) Get a mapping of the child nodes for each of the parent
nodes in the given list. It can be called directly without calling the getRootNodes()
method first. E.g. (expand action). This means that this method must be able to
initialize the handler properly so that it can answer the question of what are the
children of the parent.
The given example, generates a hierarchy of WTPart based on the
WTPartUsageLinks.
public Map<Object,List> getNodes(List parents) throws WTException {
if (configSpec == null) {
configSpec = getDefaultConfigSpec();
}
Implementing ComponentConfigBuilder
Example:
@ComponentBuilder(value = "custom.treeExample.seperate", type =
ComponentBuilderType.CONFIG_ONLY)
public class TreeExampleConfigBuilder extends
AbstractComponentConfigBuilder {
private static final String RESOURCE = "com.ptc.carambola.
carambolaResource";
@Override
public ComponentConfig buildComponentConfig(ComponentParams
params)
throws WTException {
ComponentConfigFactory factory = getComponentConfigFactory
();
//Create TreeConfig
TreeConfig tree = factory.newTreeConfig();
// Need to set DataSOurceModes explicitely to
DataSourceMode.ASYNCHRONOUS
((JcaTreeConfig) tree).setDataSourceMode(DataSourceMode.
ASYNCHRONOUS);
tree.setLabel((new ResourceBundleClientMessageSource(RESOURCE)).
getMessage
("PART_TREE_LABEL"));
Implementing ComponentDataBuilder
The concrete class should implement interface
com.ptc.mvc.components.TreeDataBuilderAsync. Please check
Java API documentation for more details.
Example:
@ComponentBuilder(value = "custom.treeExample.seperate", type =
ComponentBuilderType.DATA_ONLY)
public class TreeExampleComponentDataBuilder
implements TreeDataBuilderAsync {
@Override
public void buildNodeData(Object node,
ComponentResultProcessor resultProcessor)
throws Exception {
if (node == TreeNode.RootNode) {
List<Object> objects = getRootNodes();
resultProcessor.addElements(objects);
} else {
List nodeList = new ArrayList();
nodeList.add(node);
Map<Object, List> map = getNodes(nodeList);
List<DefaultMutableTreeNode> getDynamicExpandedNodes
(ComponentConfig config,
ComponentParams params) throws WTException;
Please refer to JavaDoc for details.
Concrete implmenetation of TreeExpansionStateManager is provided by
DefaultTreeExpansionStateManager. This implementation can be
extended to customize the APIs as per requirement or
TreeExpansionStateManager can be implemented directly. The concrete
implementation can be injected into the builder by using
ExpansionStateManager annotation.
Example:
@ComponentBuilder ("folderbrowser_tree")
@ExpansionStateManager (FolderTreeExpansionStateHandler.class)
//
public class FolderTreeBuilder extends AbstractComponentConfigBuilder
Implementing ComponentConfigBuilder
Implementing ComponentDataBuilder
In this case the databuilder should implement ComponentDataBuilder interface.
Example:
@ComponentBuilder(value = "custom.treeExample.seperate", type =
ComponentBuilderType.DATA_ONLY)
public class TreeExampleComponentDataBuilder implements
ComponentDataBuilder {
@Override
public TreeHandler buildComponentData(ComponentConfig config,
ComponentParams params) throws WTException {
return new customTreeHandler();// customTreeHandler should
implement
TreeHandler or extend TreeHandlerAdapter
}
}
Defining View
setView method on componentConfig enables setting of view for a particular
builder The view should be set relative to /WEB-INF/jsp folder. The default view
points to uses WEB-INF/jsp/components/tree.jsp
The default view can be customized using the custom tag definitions provided in
file <Windchill>\codebase\WEB-INF\tlds\jcaMvc.tld
Customization Points
Class Diagram
Sample Code
Examples of Usage in Windchill Code
• Folder Browser table
• Type Picker
• Team Tree on Home-> Team
• Preference Manager Tree
• Tree Examples under Customization Tab
Background
Windchill attempts to provide consistent attribute behavior across all client
applications. The Windchill Client Infrastructure provides support for rendering
attributes of the standard Windchill supported data types (see Attribute Types
section in this topic for more information). This infrastructure includes standard
data acquisition, rendering and form processing mechanisms and, re-usable
components for rendering the UI elements for attributes. These components honor
the meta-data from attribute definition, the configurations defined for that
attribute, and the persisted value(s) of the attribute, if any.
Windchill provides multiple configurations points for customizing an attribute’s
display and behavior. The Type and Attribute Management utility is the
recommended configuration tool. For certain cases, other configuration points
may need to be used, such as:
• Java source files of modeled Windchill classes. See “GeneratedProperty” in
Modeling Columns for more information.
• Object Initialization Rules Administration. See “About Object Initialization
Rules” in the Windchill Help Center for more information.
• Preference management. See “About the Preference Management Utility” in
the Windchill Help Center for more information.
• Profile administration. See “Profiles as a Visibility Control Mechanism” in the
Windchill Help Center for more information.
The most common configurations include:
• Constraints
• Properties that can be set on attributes in the Type and Attribute Management
utility
• Default values for attributes
Some of the other factors that implicitly affect the behavior of attributes include:
• Behavior built into the infrastructure to comply with Windchill UI standards
• DB configurations
• Attribute validators (see UI Validation on page 723 for more information)
The framework also provides extension points for customization via the ability to
override the standard rendering and data acquisition behavior. See Data Utilities
section in this topic for more information.
Terminology
Definition of some commonly used terms
Term Definition
Attribute Panel The UI for displaying attributes as name-value pairs
according to the Attribute Layout definition.
Client / Screen The end user UI in which the attributes will be
displayed. Example: Create Wizard Attributes Step.
Info Page Primary The attributes panel in the information page that is
attributes primarily used for displaying a small set of the
attributes. This is normally displayed at the top of the
info page.
Info Page Full attributes The attribute panel that is primarily used for displaying
list a larger set of attributes on an information page.
String
Default behavior and available configurations
UI Configurations: UI Configurations:
• Required Input • Visibility (see Visibility and
• Default Values Modifiability section in this topic )
• Validating Input Values and Legal • Multiple Values (Global IBAs
Value Lists Only)
• Visibility and Modifiability • Defining Custom Labels
• Multiple Values (Global IBAs • Create Hyperlinks (see
Only) Configuration Points section in this
topic )
• Defining Custom Labels
• Making a String Value All Upper
• Controlling the Size of Input Fields
Case or All Lower Case
for String Attributes
• Limiting the Length of Values
Entered for a String Attribute
Data Acquisitions Configurations: Data Acquisitions Configurations:
• Configuring the source of data (see • Configuring the source of data (see
Customizing Data Acquisition Customizing Data Acquisition
section in this topic for more section in this topic for more
information) information)
• Configuring the data utility (see • Configuring the data utility (see
Data Utilities section in this topic Data Utilities section in this topic
for more information) for more information)
UI Configurations: UI Configurations:
• Required Input • Visibility (see Visibility and
• Default Values Modifiability)
• Validating Input Values and Legal • Multiple Values (Global IBAs
Value Lists) Only))
• Visibility and Modifiability • Defining Custom Labels
• Multiple Values (Global IBAs • Date Display Format (see
Only) Configuration Points section in this
topic for more information)
• Defining Custom Labels
• Local Time Zone (see
• Date Input Field Type (see
Configuration Points)
Configuration Points section in this
topic for more information)
• Local Time Zone (see
Configuration Points section in this
topic for more information)
Data Acquisitions Configurations: Data Acquisitions Configurations:
• Configuring the source of data (see • Configuring the source of data (see
Customizing Data Acquisition Customizing Data Acquisition
section in this topic for more section in this topic for more
information) information)
• Configuring the data utility (see • Configuring the data utility (see
Data Utilities section in this topic Data Utilities section in this topic
for more information) for more information)
Integer Numbers
Default behavior and available configurations
Configurations: Configurations:
• Required Input • Visibility (see “Visibility and
• Default Values Modifiability” section in this topic
for more information)
• Validating Input Values and Legal
Value Lists • Multiple Values (Global IBAs
Only)
• Visibility and Modifiability
• Defining Custom Labels
• Multiple Values (Global IBAs
Only) • Percent (see “Configuration Points”
section in this topic for more
• Defining Custom Labels
information)
•
Currency (see “Configuration
Points” section in this topic for
more information)
Data Acquisitions Configurations: Data Acquisitions Configurations:
• Configuring the source of data (see • Configuring the source of data (see
“Customizing Data Acquisition for “Customizing Data Acquisition for
more information” section in this more information” section in this
topic for more information) topic for more information)
• Configuring the data utility (see • Configuring the data utility (see
“Data Utilities for more “Data Utilities for more
information” section in this topic information” section in this topic
for more information) for more information)
Real Numbers
A Real Number is stored as a decimal representation (e.g. 1.23).
Default behavior and available configurations
Configurations: Configurations:
• Required Input • Visibility (see “Visibility and
• Default Values Modifiability” section in this topic
for more information)
• Validating Input Values and Legal
Value Lists • Multiple Values (Global IBAs
Only)
• Visibility and Modifiability
• Defining Custom Labels
• Multiple Values (Global IBAs
Only) • Percent (see “Configuration Points”
section in this topic for more
• Defining Custom Labels
information)
•
Currency (see “Configuration
Points” section in this topic for
more information)
Data Acquisitions Configurations: Data Acquisitions Configurations:
• Configuring the source of data (see • Configuring the source of data (See
“Customizing Data Acquisition” “Customizing Data Acquisition”
section in this topic for more section in this topic for more
information) information)
• Configuring the data utility (see • Configuring the data utility (see
“Data Utilities” section in this topic “Data Utilities” section in this topic
for more information) for more information)
Configurations: Configurations:
• Required Input • Visibility (see “Visibility and
• Default Values Modifiability” section in this topic
for more information)
• Validating Input Values and Legal
Value Lists • Multiple Values (Global IBAs
Only)
• Visibility and Modifiability
• Defining Custom Labels
• Multiple Values (Global IBAs
Only) • Percent (see “Configuration Points”
section in this topic for more
• Defining Custom Labels
information)
• Measurement System (see
• Currency (see “Configuration
“Configuration Points” section in
Points” section in this topic for
this topic for more information)
more information)
•
Measurement System (see
“Configuration Points” section in
this topic for more information)
Data Acquisitions Configurations: Data Acquisitions Configurations:
• Configuring the source of data (see • Configuring the source of data (see
“Customizing Data Acquisition” in Customizing Data Acquisition in
this topic for more information) this topic for more information)
• Configuring the data utility (see • Configuring the data utility (see
Data Utilities” in this topic for more Data Utilities in this topic for more
information) information)
Boolean
Default behavior and available configurations
Configurations: Configurations:
• Required Input • Visibility (see “Visibility and
• Default Values Modifiability” section in this topic
for more information)
• Visibility and Modifiability
• Defining Custom Labels
• Defining Custom Labels
Data Acquisitions Configurations: Data Acquisitions Configurations:
• Configuring the source of data (see • Configuring the source of data (see
“Customizing Data Acquisition” “Customizing Data Acquisition”
section in this topic for more section in this topic for more
information) information)
• Configuring the data utility (see • Configuring the data utility (see
“Data Utilities” section in this topic “Data Utilities” section in this topic
for more information) for more information)
Use the “Include Blank Option” to control whether the Undefined option is
shown. For more information see Configuration Points on page 662.
Configurations: Configurations:
• Required Input • Visibility (see “Visibility and
• Default Values Modifiability” section in this topic
for more information)
• Validating Input Values and Legal
Value Lists • Multiple Values (Global IBAs
Only)
• Visibility and Modifiability
• Defining Custom Labels
• Multiple Values (Global IBAs
Only)
• Defining Custom Labels
Data Acquisitions Configurations: Data Acquisitions Configurations:
• Configuring the source of data (see • Configuring the source of data (see
“Customizing Data Acquisition” “Customizing Data Acquisition”
section in this topic for more section in this topic for more
information) information)
• Configuring the data utility (see • Configuring the data utility (see
“Data Utilities” section in this topic “Data Utilities” section in this topic
for more information) for more information)
Required Input
You want to make it compulsory that a value is provided for an attribute.
Intended Outcome
When the attribute is displayed as a Name-Value pair like in an Attribute Panel,
the attribute will be marked with an ‘*’ in front of the label.
A validation message will be thrown when the data is submitted or when the user
navigates to another screen. This message is not customizable.
Solution
The configurations required to achieve the different kinds of behavior are listed
below:
If you want to….. Configuration
Make input required on all UIs in Use the Required Constraint
which the attribute is displayed for
entry/editing
Make input required when the attribute Use the Required Constraint
does not have a UI for entering the
value, like import of data,
programmatic creation of objects
objects/attributes
Make input required for the attribute Use the Input Required property
only on a specific UI
Make input required for the attribute Use the Input Required property
only in the UI; do not enforce this
outside the UI, like when a value is
provided programmatically
Note
In tables that allow input of data, the “*” will not be added to the column
headers. This is because if a table displays more than one object type, for any
given column, some types might have the attribute configured as required and
others may not.
Solution Elements
Element Description
initialValue A property used to specify default value
(s) for an attribute. Applies to modeled
attributes only.
See the javadoc for
com.ptc.windchill.annota
tions.metadata.Generated
Property and Modeling Business
Objects on page 100 for more
information.
Default Value A configuration in the Type and
Attribute Management utility.
See the “Default Values Tab” online
help topic for more information.
Object Initialization Rule See the “Object Initialization Rules”
online help topic for more information.
Default Value Display Mode A property used to configure how
default values will be displayed in the
UI. See “Default Value Display Mode”
in Configuration Points on page 662 for
more information.
Intended Outcome
Default values are presented in the UI in one of these three modes and/or, default
values are persisted automatically:
• Default value button
• Pre-populate the field with the default value
• Do not display default value
Solution
You want to specify a default values for attributes.
The configurations required to achieve the different kinds of behavior are listed
below:
Note
Object Initialization Rule cannot be
applied on attributes that have
initial value configured in the object
model.
Specify how default values should be Use the Default Value Display Mode
presented in the UI property.
Limitations
• The default value specified in an Object Initialization Rule will not be
reflected in the Type and Attribute Management utility.
• The value set on an attribute during persistence is the value displayed for that
attribute in the UI. So when a default value is specified in the Modeled class or
the Type and Attribute Management utility, this value will be used only for
displaying in the UI. The default value will not be automatically set on an
attribute during persistence unless the default value was displayed in the UI as
the value of the attribute using one of the methods used for displaying the
Solution Elements
Element Description
Immutable constraint A constraint defined in the Type and
Attribute Management utility. See the
“Attribute Constraint Rules” online
help topic for more information.
Changeable constraint A property constraint. Applies to
modeled attributes only.
See the javadoc for com.ptc.windchill.
annotations.metadata.
PropertyConstraints and Modeling
Business Objects on page 100 for more
information.
Visibility setting in the Type and A configuration in the Type and
Attribute Management utility Attribute Management utility. See the
“Visibility Tab” online help topic for
more information.
Role-based Attribute Visibility A configuration in the Profiles
Management tool. See the “Managing
Profiles” online help topic for more
information.
Attribute validator Java classes that can be used to perform
attribute validation and filtering. See UI
Validation on page 723 for more
information
Intended Outcome
Attributes are displayed as follows in view mode for the various configurations:
Solution
The configurations required to achieve the different kinds of behavior are listed
below:
If you want to….. Configuration
Always hide an attribute Simply exclude it from the UI (i.e. do not add it to
from a specific UI, for all an attribute panel or a table configuration).
profiles
Hide an attribute from a Use the validation service.
specific UI, for all profiles,
based on specific business
Solution Elements
Element Description
Legal value list Constraint A constraint defined in the Type and Attribute
Management utility. See the “Attribute Constraint
Rules” online help topic for more information.
Enumerated list Constraint A constraint defined in the Type and Attribute
Management utility. See Attribute Constraint Rules
for more information.
EnumeratedType in See the “GenAsEnueratedType columns” section in
Modeled class definitions the “Specialized Persistence Constraints” online
help topic for more information.
Cascading Attributes Dependencies between attributes defined in the
Type and Attribute Management utility. See
Cascading Attributes Tab.
Valid Range Constraint A constraint defined in the Type and Attribute
Management utility. See the “Attribute Constraint
Rules” online help topic for more information.
upperLimit, lowerLimit A constraint defined when defining the modeled
Constraints class. See Modeling Business Objects on page 100
for more information on
PropertyConstraints. Same functionality as
the range constraint when used with Numeric
attributes.
Wildcard Constraint A constraint defined in the Type and Attribute
Management utility. See the “Attribute Constraint
Rules” online help topic for more information.
Regular expression A constraint defined in the Type and Attribute
constraint Management utility. See the “Attribute Constraint
Rules” online help topic for more information.
String format constraint A constraint defined in the Type and Attribute
Management utility. See the “Attribute Constraint
Intended Outcome
You are able to do one or more of the following:
• Restrict the input by specifying a set of valid values that the user needs to pick
from.
Example:
○ When Include Blank Option is set to true
• Allow the value of one attribute to define the value of another attribute, where
both attributes have sets of valid values defined.
• Restrict user input to be within a certain range and display a validation
message when the value is outside the range(s).
• Ensure that the user input for a String attribute conforms to a given pattern of
characters. Display a validation message when the value entered does not
conform to the pattern specified in the constraint.
• Require that user input values be unique.
Solution Elements
Element Description
upperLimit, lowerLimit Constraints A constraint defined when defining the
modeled class. See the information on
PropertyConstraint in Modeling
Business Objects on page 100 for more
information.
String length Constraint A constraint defined in the Type and
Attribute Management utility. See the
“Attribute Constraint Rules” online
help topic for more information.
Character Entry Limit The property Character Entry
Limit can be set on a modeled, global
or local attribute. See “Configuration
Points” section in this topic for more
information.
Intended Outcome
You are able to restrict the length of string attributes in the UI and/or during
persistence and provide feedback to the user when the limit is exceeded.
Byte length
The validation in the end-user UI also takes into consideration the number of
bytes needed to store the characters entered, to account for variable width
encoding and multi-byte databases.
Solution Elements
Element Description
String Length Threshold Provided as a property or a preference. See String
For Multiple Line Input Length Threshold For Multiple Line Input in
Configuration Points section in this topic for more
information.
Input Field Type Provided as a property. See Input Field Type in
Configuration Points section in this topic for more
information.
Text Input Rows Provided as a property. See Text Input Rows in
Configuration Points section in this topic for more
information.
Text Input Columns Provided as a property. See Text Input Columns in
Configuration Points section in this topic for more
information.
Intended Outcome
You are able customize the physical width and/or height of the input fields for
some string attributes.
Limitations
• The width and height are not configurable for certain special attributes like
Name and Number.
• If a string input attribute is set to span columns in a layout, the input field
width will expand to fit the combined width of the columns spanned. This will
occur even if the string input length is smaller than the spanned width.
• Column span is not supported in the Structure Browser in this release.
Solution
The combinations of the solution elements required to achieve the different kinds
of behavior are listed below:
If you want to….. Configuration
Customize the height of all input fields Use String Length Threshold For
automatically based on the string length Multiple Line Input
constraint
Override the automatic behavior Use Input Field Type
Solution Elements
Element Description
Single Value Constraint A constraint defined in the Type and Attribute
Management utility. See the “Attribute Constraint
Rules” online help topic for more information.
Delimiter for multi-valued A preference. See “Delimiter for multi-valued
attributes. attributes” in “Configuration Points” section in this
topic for more information.
No Duplicate Values A constraint that requires the set of values for a
multi-valued attribute to be distinct. Duplicate
values are not allowed.
Intended Outcome
You are able to
• enter multiple values for an attribute
• edit the values stored for an attribute
• add / remove values when editing the attribute
• require each entered value to be unique
Solution
To configure a global attribute to have multiple values, remove its Single Value
constraint. See the “Attribute Constraint Rules” online help topic for more
information.
To require each value to be unique, add the No Duplicate Values constraint.
Otherwise duplicate values are allowed.
When multiple values assigned to a global attributes are displayed in the UI in the
‘view’ mode, they are separated by commas. To customize the separator, use the
preference “Delimiter for multi-valued attributes” . See “Delimiter for multi-
valued attributes” in “Configuration Points” section in this topic for more
information.
Limitation: Support for multiple values for Alias attributes and Calculated
attributes is not available at this time.
Solution Elements
Element Description
Lower case constraint A constraint defined in the Type and
Attribute Management utility. See the
“Attribute Constraint Rules” online
help topic for more information.
Upper case constraint A constraint defined in the Type and
Attribute Management utility. See the
“Attribute Constraint Rules” online
help topic for more information.
Intended Outcome
• You are able to enter the value of a string in any case (upper, lower or mixed-
case) in the Create or Edit UIs and have it automatically stored and displayed
as either all upper-case or all lower-case.
• You are able to programmatically(using java code, import operations etc) set
the value of a string attribute in any case (upper, lower or mixed-case) in the
Create or Edit UIs and have it automatically stored and displayed as either all
upper-case or all lower-case.
Solution Elements
Element Description
Create Hyperlinks preference This preference is available in the
Attribute Handling category. See
“Create Hyperlinks” in “Configuration
Points” section in this topic for more
information.
Create Hyperlinks property Available in the Type and Attribute
Management utility Attribute
Definition. See “Create Hyperlinks” in
“Configuration Points” section in this
topic for more information.
Intended Outcome
• You are able set up a string attribute for the automatic conversion of hyperlink
text embedded in a string value to HTML hyperlinks.
• You are able to prevent the automatic conversion of hyperlink text embedded
in a string value to HTML hyperlinks.
Solution
To configure this setting for all attributes, use the Create Hyperlinks preference.
This preference is available under the Attribute Handling category.
To configure this setting for a specific attribute, use the Create Hyperlinks
property that can be set on the attribute definition in the Type and Attribute
Management utility.
Solution Elements
Element Description
Label property A property defined in the Type and
Attribute Management utility. See
“Label” in “Configuration Points”
section in this topic for more
information.
Display Name property A property defined in the Type and
Attribute Management utility Attribute
Definition. See the “Attribute
Information Page” online help topic for
more information.
rbInfo files • componentRB.rbInfo
• tableRB.rbInfo
• com.ptc.core.htmlcomp.jstable.
jstableResource
• com.ptc.core.ui.tableRB
• wt.enterprise.enterpriseResource
(this is also used as the default)
• wt.identity.identityResource
• wt.templateutil.table.tableResource
• com.ptc.windchill.cadx.ws.
wsResource
Intended Outcome
Solution
The combinations of the solution elements required to achieve the different kinds
of behavior are listed below:
Intended Outcome
The data for an attribute can be fetched from attributes other than the default.
Solution
The combinations of the solution elements required to achieve the different kinds
of behavior are listed below:
Intended Outcome
The data for an attribute can be fetched from attributes other than the default.
Solution
The combinations of the solution elements required to achieve the different kinds
of behavior are listed below:
If you want to….. Configuration
Use a custom data utility to render Example:
an attribute for the scope of a To render Number using a custom data utility
specific UI only and that attribute called MyNumberDataUtility
already has a data utility mapped
to it and, the UI is one of the 1. Define your custom data utility
following: (MyNumberDataUtility)
• an Attribute panel defined 2. In an xconf file, map the custom data
using the Type and Attribute utility to a custom attribute id
Management utility or a (myNumber). For more information see
builder class “Map the Data Utility to the Attribute
• an Table defined using the ID” section in this topic .
Type and Attribute 3. Set the Data Utility Id property of that
Management utility or a
attribute to myNumber
builder class
Use an existing data utility to In an xconf file, map the custom data utility
render an attribute in all the UIs in to a custom attribute id(myNumber)
which the attribute is rendered
Number
Note
If the above configurations do not yield the results listed above, check the
following values of these other configurations which also affect the editability
of Number in a Create or Edit UI:
• The changeable Property Constraint for a Modeled attribute. See
Modeling Business Objects for more information.
• The Type and Attribute Management utility Visibility settings. See the
“Visibility Tab” online help topic for more information.
Name
Location
The UI behavior of the Location attribute can be customized using Object
Initialization Rules (see the “About Object Initialization Rules“ online help topic
for more information). The combinations of Object Initialization Rules required to
achieve the different kinds of behavior for Location are listed below:
If you want to….. You will need to The UI the Create
configure your OIRs Wizard will look like
like this… this…
Always use the ‘server <Value algorithm=
assigned’ folder and, do "com.ptc.core.ru
not want to allow the user le.server.impl.Ge
to specify a folder. tImmutableCon
straint"/><Value
algorithm=
"com.ptc.core.ru
le.server.impl.
GetServerAssigned
Constraint"/>
Always use the pre- <Value algorithm=
generated folder defined "com.ptc.core.ru
using Object Initialization le.server.impl.Ge
Rules and, display this tImmutableCon
value in the UI and, do straint"/><Value
not want to allow the user algorithm=
to modify this value. "com.ptc.core.ru
le.server.impl.
GetServerPreGener
Principal Attributes
1. Render Principal as a link to the Principal’s information page
This behavior can be enabled/disabled by using the “Is Info Page Link”property
(see Configuration Points section in this topic for more information).
Lifecycle State
The Lifecycle State attribute can be configured to render all the lifecycle states
instead of just the current state. This can be configured by setting the “Is Render
All States” property (see Configuration Points in this topic for more information).
Note
This configuration is applied only when the attribute is displayed on a table or
on a component whose com.ptc.core.ui.resources.ComponentType is SIMPLE.
UI behavior
• When Is Render All States is set to true:
Data Utilities
Data utilities are java classes that can be used for customizations that cannot be
accomplished using the available configuration points.
A data utility is used to get the data and meta-data of an attribute and create the UI
component which will be used to render the attribute in the UI. If the data returned
by a core API is not sufficient for creating the UI component, data utilities can be
used to augment this data with additional information. The additional information
can be fetched by an additional query, a call to a service, or whatever else you can
get at via Java code.
The OOTB implementations of data utilities provide the behavior defined for
Windchill OOTB applications in accordance with Windchill UI standards.
A note on cardinality:
Property Report
This can be viewed by navigating to Customization -> Tools -> Property Report.
This is a composite report that includes the hard attributes of a type, the logical
attributes listed in the Logical Attribute Report, and the table view attributes listed
in the Available Attributes Report. You can click on each attribute to display
additional information about it, including the data utility registered for it, if any.
Note that the DefaultDataUtility will handle many attributes for which there is not
a specific data utility listed.
Not all the attributes in this report are viewable in an attribute panel. In particular,
Calculated attributes cannot typically be used in the UI.
Configuration Points
Considerations
• Type and Attribute Management utility Attribute Definition : Set using the
Attribute Information Page. The configuration applies to a specific attributes,
in all clients.
• Type and Attribute Management utility Attribute Panel Layout Definition : Set
using the Editing Group Attribute Properties window of the attribute in the
Type and Attribute Management utility. Can be used only for attribute panels
since the scope is limited to the specific panel.
Can also be set using the ComponentConfig builder, which is used for
customizing attributes on attribute panels or tables. The configuration applies
to a specific attribute in a specific UI only.
NOTE: This
attribute is
applicable
to
components
with
component
type of
SIMPLE or
TABLE
only.
Default to
false.
Distinguish Revision Specifies Not Not If not
WIP attribute whether to available at available at specified,
Versions only distinguish this level. this level. the value
between the defaults to
checked-out false.
original and OR
the working
copy. setDistin-
guishWIP-
Versions()
Character Species the Not Not setCharac-
Entry Limit maximum available at available at terEntryLi-
number of this level. this level. mit()
characters
that can be
Example:
<AvailableAttributes>
<Class name="ext.myCompany.MyCompanyChangeIssue">
<Include name="wt.change2.WTChangeIssue"/>
<Attribute id="myCompanyString"/>
<Attribute id="myCompanyInt"/>
<Attribute id="myCompanyTime"/>
</Class>
</AvailableAttributes>
• Any attributes you include in this file will be available in all tables that
include that class.
2. Modify site.xconf with the following command to include the new file in the
attribute lookup.
xconfmanager -s
com.ptc.core.htmlcomp.createtableview.AvailableAttributesDigest
er.fileLocation=/com/ptc/core/htmlcomp/createtableview/Availabl
eAttributes.xml,AvailableAttributesSite.xml
3. Propogate the xconf changes with the following command
xconfmanager -p
Applicability
This documentation should be used by a developer who is responsible for
configuring the info page for some object in one of the Windchill products. This
design pattern shows how to configured and where the configuration should be
done for the attributes table.
Participants
The readers of this documentation should have a basic understanding of JSP, tag
libraries and JSTL.
Consequences
By following this documentation the configuration of all attributes table for any
business objects should be done in a consistent manner. This will make
maintaining these attributes table much easier and more manageable task.
Solution
Overview
The attributes table component was developed using the Windchill Client
Architecture. This component provides a common layout for an object’s attributes
as it is displayed in any of the Windchill products. Using the attributes table
component will provide consistency between all objects and Windchill products.
Creating a JSP
Your attributes.JSP will have only the describeAttributesTable tag and list of
attribute names as id in describeProperty. Based on the configuration in the
describeAttributesTable, the showSoftAttribute.jspf component will render the
attributes table panel and its content.
Here is the example of attributes.jsp for document object.
<jca:describeAttributesTable var="attributesTableDescriptor"
mode=”VIEW”>
<jca:describeProperty id="<Logical Form>" />
<jca:describeProperty id="<Logical Form>" />
</jca:describeAttributeTable>
In the type input field, type the fully qualified class name and click Submit. This
should give you a listing of the attributes that can be used for the given object
type. Either the logical or the external form can be specified, although the logical
form is preferred.
wt.services/rsc/default/com.ptc.netmarkets.util.misc.FilePathFacto
ry/Attributes/wt.part.WTPart/0=/netmarkets/jsp/part/attributes.jsp
<Resource context="default"
name="com.ptc.netmarkets.util.misc.FilePathFactory">
<Option requestor="wt.part.WTPart"
resource="/netmarkets/jsp/part/attributes.jsp"
<Option requestor="wt.doc.WTDocument"
resource="/netmarkets/jsp/document/attributes.jsp"
selector="Attributes"/>
</Resource>
Sample Code
<jca:describeAttributesTable var="attributesTableDescriptor"
mode="VIEW" id="view.setAttribute"
label="Attributes" scope="request">
<jca:describeProperty id="containerName" />
<jca:describeProperty id="name"/>
<jca:describeProperty id="number"/>
<jca:describeProperty id="creatorName" />
<jca:describeProperty id="currentPrincipal" />
<jca:describeProperty id="cabinet"/>
<jca:describeProperty id="cabinetName"/>
<jca:describeProperty id="checkoutInfo.state" />
<jca:describeProperty id="comment"/>
<jca:describeProperty id="displayIdentifier"/>
<jca:describeProperty id="endItem"/>
<jca:describeProperty id="folderName"/>
Also, Edit action can be launched with below steps. The step to initially
display can be set on request with this form.
startStep=<step id>
Icon Delegates
Objective
You want to author an IconDelegate to display icon for a Windchill object
type.
Background
The purpose of object icons is to allow the user to readily distinguish between
different Windchill business objects in the Windchill UI. Its possible to associate
an icon with a Modeled type while modeling the class. This icon will be used
when an object of this type is displayed. In case of subtypes, the Type and
Attribute Management utility allows the user to associate an icon to be used to
If the user needs different icons on types (other than the OOTB) or for the
modeled/subtypes created by the user, then the user needs to author custom
IconDelegates for the respective type.
Scope/Applicability/Assumptions
User is not supposed to author custom IconDelegates for types for which
OOTB IconDelegates exists.
Intended Outcome
User is able to view the icons defined by the IconDelegate authored by the
user, for the respective Windchill type to specify your icon.
Solution
Author custom IconDelegate for Windchill type to specify your icon.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Java
• Windchill Type Identifiers
<Property>
<!-- This attribute is populated by the SCA|objectIcon
function -->
<LogicalForm>objectTooltip</LogicalForm>
<ExternalForm>NPA|objectTooltip</ExternalForm>
</Property>
Coding Pattern
Many of the IconDelegate subclasses now use an internal "params" object to
encapsulate whether or not they are working with a Persistable or a
TypeInstance. The params object has simple properties that the icon
resolution logic can use, regardless of whether the properties were populated from
a Persistable or TypeInstance.
AttributeTypeIdentifier PERSONAL_CABINET_ATI =
getIdentifier("personalCabinet", "wt.folder.Cabinet");
TypeIdentifier CABINET_TID = getIdentifier("wt.folder.Cabinet",
null);
ObjectParams(Cabinet cabinet){
if(cabinet != null)
this.cabinet = cabinet;
}
ObjectParams(TypeInstance ti){
if(ti != null)
this.ti = ti;
}
void reSetObject(Cabinet cabinet){
if(cabinet != null)
this.cabinet = cabinet;
}
boolean isPersonalCabinet(){
if(cabinet != null){
return (cabinet.isPersonalCabinet());
}else{
return (Boolean)ti.get(PERSONAL_CABINET_ATI);
}
}
}
Objective
Scope/Applicability/Assumptions
Graphical representations can only be applied to calculated attributes. Particular
representations may only apply to calculated attributes of specific data types and
may only support a well-defined subset of the possible formula results. See the
Solution Elements section for more info on the scope, configuration, and
limitations of the three out-of-the-box graphical representations.
Intended Outcome
When an attribute is configured with a custom graphical representation, it displays
as graphical throughout the product in all tables that support graphical attributes,
in information pages and wizards.
The following are examples of the three available out-of-the-box graphical
representations in various Windchill UIs:
Prerequisite Knowledge
To successfully create a new custom representation, it is helpful to have an
understanding of the following subjects:
• “Creating a New Attribute“ topic in the Windchill Help Center
• “Calculated Attribute Formulas” topic in the Windchill Help Center
Constructing and Rendering a Table Using the JSP Framework on page 564
• Attribute Customization on page 615
• The Additional Resources section in Reference on page 719includes
references to more subjects.
• The “Graphical Attributes” topic in the Windchill Help Center contains
additional information on the three out-of-the-box graphical representations.
• Reference on page 719 contains design & implementation details on the three
available out-of-the-box graphical representations. This information can be
helpful when creating your custom graphical representation.
Solution Elements
The following table lists the primary classes used to implement custom graphical
representations. Typically customizers need to extend
AbstractGraphicalComponent, and implement
GraphicalAttRepresentationHandler and GraphicalComponent.
@Override
public IconComponent getIconComponent() {
// create the icon component using the correct image
path
final IconComponent component = new IconComponent
(image);
// set the tooltip
component.setTooltip(tooltip);
return component;
}
@Override
public static RainOrShineEnum getElement(int key) throws
WTException {
for (RainOrShineEnum tls : values()) {
if (key == tls.key) {
return tls;
}
}
LOGGER.error("Undefined RainOrShineState: " + key);
LOGGER.error("Change the formula to return one of the
following states: 0, 1");
throw new WTException("Undefined RainOrShineState: " +
key);
}
}
@Override
public IconComponent getIconComponent(int key) throws
WTException {
return RainOrShineEnum.getElement(key).getIconComponent();
}
}
Testing
1. First create a new calculated attribute in the Type and Attribute Management
utility (maybe on the Document or Part type).
2. Then, on this attribute, set the “Graphical Representation” property to “Rain
Or Shine”, and set the formula to 0 or 1.
3. Save your changes.
4. Navigate to an instance of this type in Windchill (or create a new instance).
Whenever this attribute appears in “view” mode in Windchill it is displayed as the
“rain.gif “or “sunshine.gif” image!
XyzCorp.pieChart.renderer.exportRendererForGWT = function(data) {
…
return <the export value>;
};
• The first and main “renderer()” function produces the HTML that
represents this element on the rendered page. If the server sent an error string,
it should be returned as the result of this function. Otherwise, you can use the
JSON value in data to generate whatever HTML is desired.
• The second “exportRenderer()” function returns the string value to be
exported for this element. This export value may appear in any of the files
produced by the “Export List to File” action in the Windchill UI.
• The third “exportRendererForGWT()” function returns the string value
to be exported for this element in GWT, Cadx, and PSB based UIs. This export
value may appear in any of the files produced by the “Export List to File”
action in the Windchill GWT-based UIs.
• The fourth “searchFunc()” function returns the string value that
represents this element during search-in-table operations. If a search string
matches any substring of this function’s return value, the corresponding
element is included in the search results.
• Finally, the fifth “groupFunc()” function returns the label that is used to
identify the group containing this element. When a user uses the table column
header menu to “Group By This Field”, the table is sorted and any contiguous
rows of the table having the same group label is clustered together using that
label to identify the group.
• Notice that the exportRenderer, searchFunc, and groupFunc
functions are all defined on the renderer function,
XyzCorp.pieChart.renderer. This naming convention is required for
those functions to take effect. If you try to name your functions differently or
use a different prefix, they are ignored.
Limitations
The internal names of graphical attributes must be used consistently throughout
the system. Once you have chosen to use an attribute internal name for a graphical
attribute on one type you should only use that attribute internal name for the same
kind of graphical attribute anywhere you use it in the system.
If you reuse the same internal name for different purposes in this way you will see
unexpected results where sometimes you do not get the graphical representation
you expect or you get a graphical representation where you were not expecting
one at all, or you get errors in the UI.
An attribute internal name must not be used across types for a mixture of
graphical and non-graphical attributes. For example, you create an attribute named
<myGraphicalAttr> on a document and make it a traffic light. You should
not then create an attribute named <myGraphicalAttr> on part and make it
an integer. Similarly you should not mix graphical attribute types with one internal
name. You should not create an attribute called <myGraphicalAttr> on
another type that is using a graphical representation other than traffic light.
Making mixed use of an attribute internal name is not supported.
Performance Considerations
Please be aware that since graphical representations are rendered throughout the
Windchill user interface, they have the potential to impact the performance of
rendering attributes in the UI. In particular if you define many graphical attributes
and then create a custom table view that contains many columns of graphical
attributes, rendering performance of the table may potentially suffer.
Location of Example
This example can be viewed in the Windchill product by navigating to
Customization ▶ Component Catalog ▶ Graphical Attributes ▶ Examples section ▶
Graphical Attributes in Configurable Table Example
Example FIles
Files used in this example can be found in the Carambola source tree:
• src/com/ptc/mvc/builders/carambola/table/
CarambolaGraphicalAttributesConfigurableExampleTable
Builder.java
• src/com/ptc/mvc/builders/carambola/table/
CarambolaGraphicalAttributesExampleTableDataBuilder.
java
• src/loadFiles/customization/LiteratureSoftTypes.xml
• src/loadFiles/customization/WidgetSoftTypes.xml
• src_web/config/actions/Carambola-actions.xml
Location of Example
This example can be viewed in the Windchill product by navigating to
Customization ▶ Component Catalog ▶ Graphical Attributes ▶ Examples section ▶
Graphical Attributes in Non Configurable Table Example
Example Files
Files used in this example can be found in the Carambola source tree:
• src/com/ptc/mvc/builders/carambola/table/
CarambolaGraphicalAttributesExampleTableBuilder.java
• src/com/ptc/mvc/builders/carambola/table/
CarambolaGraphicalAttributesExampleTableDataBuilder.
java
• src/loadFiles/customization/LiteratureSoftTypes.xml
• src/loadFiles/customization/WidgetSoftTypes.xml
• src_web/config/actions/Carambola-actions.xml
Reference
This section contains details on the three out-of-the-box graphical representations.
The information in this section is provided as background details on how the three
out-of-the-box graphical representations (Traffic Light, Progress Bar, and Percent
Complete) are configured and implemented. This information can be valuable
when creating your own custom graphical representation.
The diagram below is a partial representation of how these classes have been
extended to implement the OOTB graphical representations.
Solution Elements
The code specific to the Traffic Light representation includes:
Solution Elements
The code specific to the Progress Bar representation includes:
Element Type Description
ProgressBarCompo Java Class This class defines and
nent supports the out of the
box graphical
representation of
“Progress Bar.” It is a
subclass of
AbstractGraphical
Component. Unlike the
traffic light, this
component does not
leverage an existing
component, so it also
defines a new JavaScript
renderer (called
PTC.progressBar.
renderer).
progressBarRender JS Class This class defines the
er.jsfrag JavaScript renderer for
the progress bar,
converting the JSON
containing the progress
meta-data into the
corresponding HTML
(with an appropriate
tooltip).
Solution Elements
Element Type Description
PercentComplete Java Class This is the class that
Component defines and supports the
out of the box graphical
representation of “Percent
Complete.” It is a
subclass of
ProgressBarCompo
nent. Because this
graphical representation
leverages the
ProgressBarCompo
nent, it also utilizes the
PTC.progressBar.
renderer JS renderer.
Additional Resources
UI Validation
Objective
You want to hide an action or attribute in the UI based on some context
information.
• You want to determine whether or not an action selected in the UI should be
allowed to proceed based on some context information.
Background
UI Validation is intended to simplify the experience of the Windchill end-user.
There are three categories of UI Validation that will each be discussed in further
detail in this document.
• Pre-Validation
• Post-Select-Validation
• Post-Submit Validation
Pre-Validation
The first category of UI Validation is referred to as Pre-Validation. This is the
category of validation that most people will first associate with UI Validation. Pre-
Validation is a term that describes the process of determining whether or not a UI
Component should be available in the UI. An example of Pre-Validation would be
disabling the “check-in” action for an object that is not checked-out. Pre-
Validation can be applied to both actions and attributes in the UI. Of the three
types of UI Validation, this type is the most often-used.
Post-Select Validation
A second category of UI Validation is Post-Select Validation. Post-Select
Validation is the process of determining whether or not an action should be
allowed to proceed once it is selected in the UI. An example of post-select
validation would be displaying an error message and not allowing the checkout to
proceed if a user tries to perform a checkout on an object that is already checked
out. Post-Select Validation applies only to actions.
Post-Submit Validation
The final category of UI Validation is Post-Submit Validation. This type of
validation is used exclusively in wizards or other forms where users enter data. An
example of Post-Submit Validation would be stopping a user from moving to the
next step in a wizard because the data they’ve entered in the current step is
invalid. Post-Submit Validation applies only to wizard steps and wizard
submissions.
Scope/Applicability/Assumptions
• Pre-Validation - Suppose you want to hide an action in the UI from users who
are not members of the current container’s team.
Intended Outcome
• Pre-Validation - Before the page is rendered, you are able to determine
whether or not the user is a member of the current container’s team. If not, the
action is not displayed on the page.
• Post-Select Validation - After the user invokes the action, you are able to
check the target object’s lifecycle state. If the state is not the state you require,
you can display a message to the user, and the action is not performed.
• Post-Submit Validation - When the user clicks “next” on the wizard, you get
the data entered in the current step and are able to determine whether or not it
is adequate to allow the user to proceed to the next step. If the data is
inadequate or invalid, you can display a message to the user and not allow
them to proceed to the next step.
Solutions
• Pre-Validation - Determine whether the business logic is specific to a single
action or attribute, or if the same logic could apply to multiple actions or
attributes. If the logic is specific to a single UI Component (action or
attribute), add the logic to a Validator. If the logic could apply to multiple UI
Components, add the logic to a Filter. Finally, associate the Validator or Filter
with the UI Component to ensure that the business logic is applied to that
component.
○ Pre-Validation in a Validator - Implement the performFullPreValidation()
and performLimitedPreValidation() methods in a Validator to contain the
desired business logic.
○ Pre-Validation in a Filter - Implement the preValidateAction method in a
Filter to contain the desired business logic.
• Post-Select Validation - Implement the validateSelectedAction() and
validateSelectedMultiSelectAction() methods in a Validator to define the
desired business logic, and associate the Validator with the action.
• Post-Submit Validation - Implement the validateFormSubmission() method in
a Validator to define the desired business logic, and associate the Validator
with the wizard step or the entire wizard.
Solution Elements
In addition to the solution elements involved in UI Validation, this section also
contains some definitions of key terms (in bold italic).
Element Type Description
StandardUIComponentValida- Java class Often referred to as the
tion Service validation service. This is the
service class that controls UI
Validation. It receives validation
requests from the client
infrastructure and delegates to
the appropriate validators and
filters for validation results. It
then passes the validation results
back to the client infrastructure.
Customizers and application
developers should not have to
interact directly with this class.
UIValidationKey Java class Often referred to as a validation
key. A UIValidationKey is used
to identify the UI Component
being validated. You can think of
a UIValidationKey as having a
one-to-one relationship with an
action or attribute.
UIValidationCriteria Java class Often referred to as the
validation criteria.
Pre-Validation Sequence
The pre-validation sequence begins with the client infrastructure (typically, but not
exclusively, the StandardNmActionService) sending a list of UI components to the
validation service. The expectation is that for each of those UI components, the
validation service will return a validation result indicating the display status for
Key
1. The Client Infrastructure calls the validation service, passing an action
(represented by a validation key) corresponding to the page being rendered,
and the context data (represented by a validation criteria instance).
Once the validation service receives the validation request from the client
infrastructure, the validation service iterates through each of the validation keys,
and performs several tasks to determine the validation status for each of the keys.
The first such task that the validation service performs is to see whether or not a
given validation key represents a component that should be hidden, based on the
PTC solutions that are installed. This is accomplished by referencing a cache of
invalid validation keys that is created when the validation service is first started.
To create the cache, the validation service simply calls all registered solution
groups and asks for a list of invalid validation keys from each of them, based on
the installed solutions.
Key
1. The Client Infrastructure calls the validation service, passing an action
(represented by a validation key) corresponding to the page being rendered,
and the context data (represented by a validation criteria instance).
2. For each validation key, the validation service performs a series of tasks to
determine the validation status for that key. The tasks are executed in the
following order:
a. Check to see if the validation key is in the list of invalid keys for the
installed solution set.
The second pre-validation check performed by the validation service is to see
whether or not the component is hidden or disabled by the role-based UI service.
The role-based UI service was introduced in 8.0 as a way for admin users to
configure the display of UI components based on a user’s role. With the
introduction of the UI Validation Service in 9.0, the role-based UI service has
become a special delegate of the UI Validation Service.
If the role-based UI service returns a status of “hidden” or “disabled”, the
validation service sets the component’s status correspondingly and does not
perform any additional validation on the component. Otherwise, if the role-based
UI service returns an “enabled” status, the validation service continues with its
pre-validation checks.
Assuming the role-based UI service says the component should be enabled, the
validation service will next check to see if any filters are associated with the UI
component.
To determine which filters should be applied to a UI component, the validation
service references some additional cached data that is stored when the validation
service is first started. The first cache referenced contains a list of all registered
universal filters. When a filter is defined and registered as a universal filter, it is
automatically applied to all UI components by default. If any universal filters are
found in this cache, they are automatically added to the list of filters that will be
applied to a given UI component.
Although universal filters are applied to all UI components by default, there is
support for configuring actions to ignore individual universal filters. (Currently,
there is no similar support available for configuring attributes to ignore universal
Key
1. The Client Infrastructure calls the validation service, passing an action
(represented by a validation key) corresponding to the page being rendered,
and the context data (represented by a validation criteria instance).
2. For each validation key, the validation service performs a series of tasks to
determine the validation status for that key. The tasks are executed in the
following order:
a. Check to see if the validation key is in the list of invalid keys for the
installed solution set.
b. Check to see if the role-based UI service was configured to disable or
hide the component.
c. Check to see if any of the filters associated with the UI component
indicate that the component should be disabled or hidden.
(See the diagram on the following page for additional details.)At this point, the
validation service has completed its validation checks for each UI component. If
the client infrastructure passed a single UI component to the validation service to
be pre-validated, the validation service will return a single validation result to the
caller. If multiple UI components were passed to the validation service for pre-
Key
1. The Client Infrastructure calls the validation service, passing an action
(represented by a validation key) corresponding to the page being rendered,
and the context data (represented by a validation criteria instance).
After receiving a post-select validation request from the client infrastructure, the
validation service checks to see if there is a validator associated with the specified
action.
As is the case with pre-validation, a validator is associated with an action by
creating an entry in a service.properties.xconf file that links the action id to the
class name of the validator class for that action.
Key
1. The Client Infrastructure calls the validation service, passing an action
(represented by a validation key) corresponding to the page being rendered,
and the context data (represented by a validation criteria instance).
2. The validation service checks to see if there is a validator associated with the
action. If so, it calls the validator to get the validation status (permitted or
denied) for the action.
After the validator returns its validation result, the validation service simply
passes along the validation result returned by the validator to the client
infrastructure. The client infrastructure will check to see whether that status is
“permitted” or “denied”. If the status is “permitted”, the page or wizard is
Key
1. The Client Infrastructure calls the validation service, passing an action
(represented by a validation key) corresponding to the page being rendered,
and the context data (represented by a validation criteria instance).
2. The validation service checks to see if there is a validator associated with the
action. If so, it calls the validator to get the validation status (permitted or
denied) for the action.
3. The validation service passes the validation status (wrapped in a validation
result) from the validator to the client infrastructure, which either displays the
target page/wizard, or brings the user back to the page where the action was
invoked.
Key
1. The Client Infrastructure calls the validation service, passing an id associated
with a wizard's "Next" or "OK" action (represented by a validation key), and
the context data (represented by a validation criteria instance).
After receiving a post-submit validation request from the client infrastructure, the
validation service checks to see if there is a validator associated with the wizard’s
“Next” or “OK” action.
As is the case with pre-validation and post-select validation, a validator is
associated with a wizard’s “Next” or “OK” action by creating an entry in a
service.properties.xconf file that links the action id to the class name of the
validator class for that action.
Key
1. The Client Infrastructure calls the validation service, passing an id associated
with a wizard's next or OK action (represented by a validation key), and the
context data (represented by a validation criteria instance).
2. The validation service checks to see if there is a validator associated with the
"Next" or "OK" action. If so, it calls the validator to get the validation status
(permitted or denied) for the action.
After the validator returns its validation result, the validation service simply
passes along the validation result returned by the validator to the client
infrastructure. The client infrastructure will check to see whether that status is
“permitted” or “denied”. If the status is “permitted”, the user is allowed to proceed
to the next step in the wizard, or complete the wizard submission. If the status is
Key
1. The Client Infrastructure calls the validation service, passing an action
(represented by a validation key) corresponding to the page being rendered,
and the context data (represented by a validation criteria instance).
2. The validation service checks to see if there is a validator associated with the
"Next" or "OK" action. If so, it calls the validator to get the validation status
(permitted or denied) for the action.
3. The validation service passes the validation status (wrapped in a validation
result) from the validator to the client infrastructure, which either allows the
user to proceed to the next step in the wizard or submit the entire wizard, or
brings the user back to the wizard step where the action was invoked.
Procedure – Pre-Validation
This section describes the steps you should perform for various operations related
to pre-validation.
• Distinguishing between Pre-Validation Statuses
• Implementing Role-Based Pre-Validation
For other steps, see:
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import wt.log4j.LogR;
import wt.util.InstalledProperties;
/*
* ADD ADDITIONAL SOLUTION-BASED CHECKS AS NEEDED
*/
if (logger.isTraceEnabled()){
logger.trace("RETURNING " + (List)invalidList);
}
(logger.(trace("RETURNING " + (List)invalidList))){
logger.debug("EXITING MySolutionGroup.getInvalidKeys");
}
return invalidList;
}
}
Once your solution group is registered, its logic should be checked any time the
validation service is called to perform pre-validation. (Its results are actually
cached after the first invocation.)
Registering Filters
Once you've created a filter, the next step is to register it.
Depending on the type of filter you implement (universal or simple), your filter
registry will differ. When providing a selector in your registry, the convention is to
use the filter class name with replacing the first letter with a lower-case letter, and
eliminating the "filter" suffix (e.g., "MarkedForDeleteFilter" would have a
selector of "markedForDelete"). The following details should clarify:
To register a universal filter, in *service.proeprties.xconf, create an entry like this:
<Service context="default"
name="com.ptc.core.ui.validation.UniversalValidationFilter">
<Option
serviceClass="com.ptc.windchill.enterprise.markedfordelete.validat
ors.MarkedForDeleteFilter"
selector="markedForDelete" requestor="null" />
</Service>
<Service context="default"
name="com.ptc.core.ui.validation.SimpleValidationFilter">
<Option
serviceClass="com.ptc.windchill.enterprise.somepackage.validators.
MarkedForDeleteFilter"
selector="markedForDelete" requestor="null" />
</Service>
Note
The name attribute of the excludeFilter element should correspond to the
selector used to register the filter in *service.properties.xconf.
resourceBundle="com.ptc.windchill.enterprise.change2.changeManagem
entActionsRB">
<action name="create" >
<command class=…/>
<includeFilter name="problemReportStatus" />
</action>
<action name="edit" >
<command class=…/>
<includeFilter name="problemReportStatus" />
</action>
<action name="editModifyContentOnly"
id="editModifyContentOnly">
<command class="…/>
Note
Again, the name attribute of the includeFilter element should correspond to
the selector used to register the filter in *service.properties.xconf.
Note
The order of the includeFilter and excludeFilter elements does not matter, nor
does it have any bearing on the order in which the filters are called.
Note
The name attribute of the excludeFilter element should correspond to
the selector used to register the filter in
*service.properties.xconf.
Note
The name attribute of the includeFilter element should correspond to
the selector used to register the filter in
*service.properties.xconf.
Note
The order of the includeFilter and excludeFilterelements does
not matter, nor does it have any bearing on the order in which the filters are
called.
import com.ptc.core.ui.validation.DefaultUIComponentValidator;
@Override
public UIValidationResultSet performLimitedPreValidation()
(UIValidationKey validationKey,
UIValidationCriteria validationCriteria, Locale
locale) throws WTException {
UIValidationResultSet resultSet =
UIValidationResultSet.newInstance();
return resultSet;
}
}
Registering Validators
Once you’ve created your validator and implemented the appropriate pre-
validation method(s), the only thing left to do is to register it. You need to register
your validator to associate it with the action or attribute it is intended to validate.
When registering a validator for an action, you may make the association using
the action name only, or using a combination of action name and object type. In
most cases, using just the action name to identify your validator is sufficient and
preferred. When registering a validator for an attribute, you make the association
using the attribute’s descriptor ID.
Basic Validator Registration
To register your validator (using only the action name for an action), you need to
add an entry to *service.properties.xconf like this:
<Service context="default"
name="com.ptc.core.ui.validation.UIComponentValidator">
• Note that in this case, the requestor attribute is null, meaning the action’s
object type is not used in the lookup.
Type-Based Validator Registration
If you feel you have a case where it makes sense to register your validator using
an action’s object-type in addition to action name, it is very similar to registering a
validator using only the action name. The difference lies in the requestor attribute
in the properties entry. For validators that do not use an object type, the requestor
attribute is set to null. For a validator to be registered using object type, the
requestor value will be the fully-qualified class name of the type it is to be
registered for.
The class name that is used in the requestor attribute corresponds to a class name
from actions.xml.
For example, consider this fragment of an actions.xml file (NOTE: some text
eliminated for readability):
<objecttype name="problemReport" class="wt.change2.WTChangeIssue"
...>
<action name="create" >
...
</action>
...
</objecttype>
In this case, the action we're looking at is called create. Obviously, it's likely that
there will be multiple actions defined in the system named create. However, the
validation rules for each create action may be different, depending on the type of
object being created. Therefore, it might make sense to have separate validators
for the create action for, say, a Problem Report and the create action for a Part.
Suppose we have a validator defined called com.ptc.windchill.enterprise.change2.
validators.ChangeMgmtCreateWizardsValidator that we want to register for create
actions, but only if the action is to create a Problem Report.
serviceClass="com.ptc.windchill.enterprise.change2.validators.Chan
geMgmtCreateWizardsValidator"
selector="create" requestor="wt.change2.WTChangeIssue" />
</Service>
That's really all there is to it. Basically, if you want to register your validator for
an action, but only if that action is associated with a certain object type (in actions.
xml), you use the class attribute from actions.xml as the requestor attribute in your
properties entry.
A few notes:
• This type-based lookup is currently only available for actions defined in
actions.xml. It will not work for attributes or other UI components.
• For this to work, the class attribute from your actions.xml entry needs to be a
concrete class (not an interface - there are many cases where the class attribute
is currently set to wt.fc.Persistable). Changing an existing class attribute from
an interface to a concrete class is OK in most cases. But you should check
with the owner of the actions.xml file you're modifying before doing so.
Verifying Validator Registration
There is a command line report you can run to see which validators are registered
for a given action or attribute. If your validator is not appearing in this report, that
means it is not registered correctly, and will never get called.
Examples follow:
Finding a single validator (non-type based)
• Usage example 1 - find the validator registered for the pasteAsCopy action:
Y:\>java com.ptc.core.ui.validation.UIComponentValidatorFactory
pasteAsCopy
Registered validators:
pasteAsCopy ->
Registered validators:
setState ->
com.ptc.windchill.enterprise.lifecycle.validators.SetStateValid
ator
pasteAsCopy ->
com.ptc.core.foundation.saveas.validators.PasteValidator
Registered validators:
create:problemReport(wt.change2.WTChangeIssue) ->
com.ptc.windchill.enterprise.change2.validators.ChangeMgmtCreat
eWizardsValidator
Registered validators:
pasteAsCopy ->
com.ptc.core.foundation.saveas.validators.PasteValidator
create:problemReport(wt.change2.WTChangeIssue) ->
com.ptc.windchill.enterprise.change2.validators.ChangeMgmtCreat
eWizardsValidator
Creating a Validator
Creating a validator for post-select validation is exactly the same as creating a
validator for pre-validation. SeeProcedure – Pre-Validation on page 746 for
details.
@Override
public UIValidationResultSet validateSelectedMultiSelectAction
() (UIValidationKey validationKey,
UIValidationCriteria validationCriteria, Locale
locale) throws WTException {
UIValidationResultSet resultSet =
UIValidationResultSet.newInstance();
return resultSet;
}
Creating a Validator
Creating a validator for post-submit validation is exactly the same as creating a
validator for pre-validation. SeeProcedure – Pre-Validation on page 746 for
details.
UIValidationStatus.NOT_VALIDATED);
return result;
if
(!WTPart.class.isAssignableFrom(contextObjectRef.getReferencedClas
s())){
...
}
if (!PDMLinkProduct.class.isAssignableFrom(containerRef.getReferenced
Class())){
...
}
}
.equals(GenericType.GENERIC)){
...
And that may work fine in your test cases where you're only testing an action on
part details pages. But what if that action also appears in the toolbar of one of the
tables on the home page, or on the products list page? Then the code above will
throw a NullPointerException from those pages, since validationCriteria.
getContextObject() will (correctly) return null.
NOT
if
(validationCriteria.getComponentType().equals(ComponentType.WIZARD
))
In general, just because a null value doesn't allow validation to proceed in your
use case, that doesn't mean it should be a showstopper in every use case.
UIValidationCriteria.toString()
UIValidationCriteria, the toString() is not over-ridden to give information of its
content. You can use the following method for logging.
public String toString_heavy(Logger logger, Level level)
If the Level of the Logger matches with the Level provided, the method will
return the information. Since the method performs some costly calculations, it’s
suggested to use this it wisely.
URL Authorization
Objective
You want to use a consistent process for validating authorization to view a URL
and present a uniform error page when an unauthorized view is attempted.
Background
A framework is available in Windchill that can be used to apply additional access
control verification on JCA and Template Processor based pages. When this
validation process is enforced on a URL, unauthorized attempts to view the page
Scope/Applicability/Assumptions
The URL validation process can be extended to JCA and Template Processor
pages only. Extending this functionality to GWT-based pages is not supported.
Intended Outcome
Before a page is displayed, you are able to determine whether or not the user is
authorized to view a page when they access it from a known URL. If they are
denied access, a consistent error page is displayed.
Solution
Author a custom URL validator for the page to which you want to extend the URL
validation process.
Prerequisite Knowledge
To achieve this objective, you need to have an understanding of JCA or Template
Processor pages, depending on the type of the page for which you are creating a
custom URL validator. You will also need to know the Component ID for the
URL of the page for which you wish to restrict access.
Solution Elements
• Your custom validator should extend
com.ptc.core.ui.validation.DefaultURLValidator
• You can override an existing out-of-the-box validator with your own custom
validator. To do this, register your validator for the URL in WT_HOME/
codebase/config/urlValidators/custom-validators.xml
• Override public UIValidationStatus preValidateAction (UIValidationKey
validationKey, UIValidationCriteria validationCriteria) method.
• UIValidationStatus.PERMITTED means that the URL is accessible
and all other statuses means the URL is not accessible
• Note that the URL Validation service will not execute other available methods
in DefaultURLValidator.
Possible attributes of urlvalidator elements are listed in the following table.
Parameter Default Value Possible Required? Description
Values
url n/a Any Yes The
combination of Component ID
alpha-numeric for the URL
characters for which the
Note
Either uicomponent or class is required, otherwise an error will log in the MS
server start-up.
Registering Validators
Configuration Files
The runtime location for the configuration files are in WT_HOME/codebase/
config/urlValidators and they should follow the naming convention of
*-validators.xml. The .dtd that is applied is urlValidators.dtd and
it is available in the same location, as well as custom-validators.xml,
which should be used for custom validators.
Caution
If you perform this customization you must maintain and carry-forward this
customization when you move to a later release of Windchill.
Note
If you want to allow leading or trailing spaces, perform steps 1 and 3 below;
otherwise step 2 is sufficient.
if (value != null) {
value = value.trim();
if (value.equals("")) {
value = null;
}
}
return value;
}
return value;
}
Sample Code
// Generated DefaultValidateFindNumbersDelegate%43C7A40F0161: Fri
03/07/08
10:41:32
/* bcwti
*
* Copyright (c) 2007 Parametric Technology Corporation (PTC). All
Rights
* Reserved.
*
* This software is the confidential and proprietary information
of PTC
* and is subject to the terms of a software license agreement.
You shall
* not disclose such confidential information and shall use it
only in acco
rdance
* with the terms of the license agreement.
*
* ecwti
*/
package wt.part;
import java.lang.String;
import wt.part.ValidateFindNumbersDelegate;
import wt.part.WTPartUsageLink;
import wt.util.WTException;
//##begin DefaultValidateFindNumbersDelegate%43C7A40F0161.doc
preserve=no
/**
* Standard delegate to handle validation of Find Numbers, i.e.,
OOTB behavior,
* which is doing nothing.
*
//##end validateFindNumbers%43C6C7F300E8.body
}
if (a_FindNumber != null) {
for (int i = 0; i < a_FindNumber.length(); i++) {
if(a_FindNumber.startsWith(HYPHEN) ||
(a_FindNumber.endsWith(HYPHEN)))
{
Object[] args = {a_FindNumber};
throw new WTPropertyVetoException( RESOURCE,
wt.part.partResource.FIND_NUMBER_NOT_ALPHANUMERICAL_ERROR, args,
new java.beans.PropertyChangeEvent(
this, "findNumber",
a_FindNumber, a_FindNumber ));
}
if (!Character.isLetterOrDigit(a_FindNumber.
charAt(i))) {
if((a_FindNumber.substring(i, i + 1)).equals
(SPACE) ||
(a_FindNumber.substring(i, i + 1)).
equals(HYPHEN))
{
// We have already checked that the first
and/or
// last character is not an hyphen
// in the if-condition above. So, if the
code gets
// into this block, we can be sure
// that the hyphen is in the middle of the
// string and not at the beginning or end.
// Also, if the character is a space, we are
// allowing it, so we can continue.
continue;
}
else
{
Object[] args = {a_FindNumber};
throw new WTPropertyVetoException(
RESOURCE,
wt.part.partResource.FIND_NUMBER_NOT_ALPHANUMERICAL_ERROR, args,
new java.beans.
PropertyChangeEvent( this,
"findNumber", a_FindNumber, a_FindNumber ));
}
}
}
}
Background
This topic details the information to needed to develop inline messages using out-
of-the-box components as building blocks.
Intended Outcome
An inline message is displayed in the browser to the end user with the intended
message(s).
Solution
Use common JavaScript and java class components to display inline message that
gives user feedback about success or failure or warning message(s) for their
actions.
Prerequisite Knowledge
To apply this process, you need to have an understanding of the following:
• Java programming
• Basic web development using JavaScript, JSPs , custom tags, and HTML
forms
Customization Points
The out-of-the-box JCA framework has Inline Success message displayed in UI
for successful object creation.
Sample Code
The sample code for showing inline message for message type SUCCESS using
JavaScript function:
PTC.messaging.showInlineMessage(
[{
MessageType:'SUCCESS',
MessageTitle:'Confirmation: Create successful',
Additional Resources
The following customization topics contain related information:
• Windchill Client Architecture Overview on page 223Adding Custom Code to
all Windchill Client Architecture Pages on page 245
Javascript Functions Overview on page 238
Customizing the UI with Ajax on page 277
Constructing Wizards on page 790
Constructing and Rendering a Table Using the JSP Framework on page 564
URL Details
• The wt.whc.url property in the wt.properties file defines the URL to
the WHC.
• The wt.help.HelpLinkHelper.createHelpHREF(String) API
returns the correct fully qualified WHC URL.
This section explains how to link to help topics in the WHC from the Windchill
UI.
Information Pages
The help button ( ) will appear in the upper right corner of the information page
if you set a help context in your info builder:
// sets the help topic to use from the Windchill Help Center
infoConfig.setHelpContext("HelpTopicName");
Table/Tree
The help button ( ) will appear in the upper right corner of the table/tree if you
set a help context in your builder:
// sets the help topic to use from the Windchill Help Center
tableConfig.setHelpContext("HelpTopicName");
If your table/tree is still defined in a jsp instead of with a builder, adding the help
topic would be as follows:
<renderTable model="${tableModel}" helpContext=" HelpTopicName"/>
Wizards
The help button ( ) will appear in the upper right corner of the wizard if you
specify a help selector key in the wizard tag:
<jca:wizard helpSelectorKey="HelpTopicName" …>
Background
Wizards are popup windows that are used to guide you step by step through the
process of creating an object, or performing an operation on an object. A wizard is
a user interface consisting of a sequence of steps that lead the user through a
specific task one step at a time, the user clicks next to move through the steps. It
might not be necessary to complete all the steps present in a wizard. Once the
required information is provided, you can click FINISH / OK button to submit the
data to the server. A wizard can consist of one or many steps which must be
completed in a certain order.
The layout for single step wizards and multi step wizards will be different. The
single step wizard will not have “Step icons”, “Step links” and “Back / Next
navigation buttons”.
Scope/Applicability/Assumptions
• A wizard should be used when you need to create / edit object(s) by
performing any operations on it after collecting required information in a
specific systematic manner.
• A table rendered within a wizard is JCA table and table rendered inside a
picker is a JSCA table.
• For the most part, clerks are implemented in the same fashion as that of
wizards and the instructions in this document are applicable to both. Any
differences are noted. Otherwise, the term "wizard" should be interpreted as
either a wizard or a clerk and "wizard step" should be interpreted as either a
wizard step or a clerk tab.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development, which involves HTML, JSP, Java, JavaScript and Custom
taglibs.
• Overview of Windchill Client Architecture tags.
• The actions framework in the Windchill client architecture.
• Action validation framework.
Solution Elements
Element Type Description
components.tld tld Tag Library
Descriptor (TLD)
file, which contains
Wizard Tag and
Wizard-Step Tag
definition
Run time Location:
<Windchill>
\codebase\WEB-
INF\tlds\
wizard.js Js Contains all the
necessary logic of
how to move from
one step to another
and how to call
methods defined for
each of the steps.
Run time Location:
<Windchill>
\codebase
\netmarkets\tlds
\javascript\compon
ents
<your_wizard_ page>.jsp jsp The jsp file in
which your wizard
implementation is
defined.
<action name="affectedAndResultingItemsStep">
<command windowType="wizard_step" />
</action>
</objecttype>
The command class is the java class that should be called to process the wizard
data. Typically, this will extend CreateObjectFormProcessor.
Note that it is not necessary to specify a “method” attribute in the command tag if
the form processor class extends DefaultObjectFormProcessor or
CreateObjectFormProcessor.
Note that the “windowType” attribute of the command subtag for steps should
always be set to “wizard_step.”
Optional action tag attributes are shown in the table below.
After defining the wizard type as "clerk", the wizard will be displayed as per the
Clerk UI standards. Step indicators will not appear and step titles will be displayed
as tabs. The Next and Previous buttons will not be displayed for Clerk. The user
can navigate from any step to any step without entering the required fields. The
validation for required fields will be done when the user clicks on the "OK"
button. The user will be shown a message about required fields and will be taken
to the appropriate steps, where required fields are not populated.
The Clerk Component has a provision through which application developers can
call their specific validation logic.
For example: An application developer can write following code in jsp file to call
javascript() on “OK” Button.
<script>
Event.observe($("PJL_wizard_ok"), 'click',
userdefinedjavascriptFunction );
</script>
Customization Points
This section contains the following topics:
• <action>.xml attributes on page 800
• <wizard> tag attributes on page 802
• <wizardStep> tag attributes on page 803
• Providing user defined buttons to Wizard on page 804
• Providing user defined form processor controller on page 805
• Providing server side validation before / after processing a wizard step on page
806
• Loading the wizard step content when it is visited on page 806
• Marking a wizard step as “required” on page 807
• Hiding a wizard step on page 807
• Displaying the hidden / dynamic step at runtime on page 808
• Providing user defined SUBMIT function on page 810
• Providing client side validations before a wizard step is displayed on page 810
• Providing client side validations after a wizard step is finished on page 811
<action>.xml attributes
Parameter Default Possible Values Req? Description
Value
name None Any string Yes The name of the action.
Used as the “name”
attribute on wizard step
tags.
id <type>. Any String No Overrides the id of the
<action> wizard step (default is
type.action). Used to
identify the step in
Note
For a clerk, only the OK and Cancel buttons are displayed by default. If new
buttons are to be configured, the appropriate button model should be
configured.
...
</jca:wizard>
Note
For more information see the Wizard Processing on page 819 section.
OR
<action name="setAttributesWizStepForCreateMultiPart" afterVK =
"nameNumberValidation">
<command windowType="wizard_step"/>
</action>
<Service context="default"
name="com.ptc.core.ui.validation.UIComponentValidator">
<Option requestor="null" selector="nameNumberValidation"
serviceClass="com.ptc.windchill.enterprise.part.validator.CreateMul
tiPartNameNumberValidator" />
</Service>
You can also mark a wizard step as “required” at runtime. You need to use a
javascript function called “setStepRequired” which is defined in main.js file. You
need to pass the “id” of the step. The default id of the step is in the format
“<type>.<action>”. Use the value of the “id” attribute if it is defined explicitly
while defining wizard step action. For example:
<table border="0">
<tr>
<td align="left" valign="top" NOWRAP>
<w:radioButton id="copy" name="<%=NmObjectHelper.CHOICE%>"
value="<%=NmObjectHelper.CB_COPY%>" checked="true"
onclick="setStepRequired(<type>.<action >);"/>
</td>
</tr>
</table>
To implement first way of hiding a step, you can make use of the “hidden”
attribute of <action> tag. For example:
In <*-actions>.xml
<action name="setClassificationAttributesWizStep" hidden="true">
<command windowType="wizard_step"/>
</action>
To hide a wizard step at runtime, you need to use a javascript function called
“removeStep” which is defined in main.js file. You need to pass the “id” of the
step that needs to be removed. The default id of the step is in the format “<type>.
<action>”. Use the value of the “id” attribute if it is defined explicitly while
defining wizard step action. For example:
In <your_wizardstep_page>.jsp
<table border="0">
<tr>
<td align="left" valign="top" NOWRAP>
<w:radioButton id="copy" name="<%=NmObjectHelper.CHOICE%>"
value="<%=NmObjectHelper.CB_COPY%>" checked="true"
onclick="removeStep(<type>.<action >);"/>
</td>
</tr>
</table>
Note
Clerk does not use the of conditional display of steps (i.e. hidden steps), so all
the steps will be preloaded and displayed to the user.
In <*-actions>.xml
<action name="setClassificationAttributesWizStep" hidden="true">
<command windowType="wizard_step"/>
</action>
In <your_wizardstep_page>.jsp
<table border="0">
<tr>
<td align="left" valign="top" NOWRAP>
<w:radioButton id="copy" name="<%=NmObjectHelper.CHOICE%>"
value="<%=NmObjectHelper.CB_COPY%>" checked="true"
onclick="insertStep(<type>.<action>);"/>
</td>
</tr>
</table>
setUserSubmitFunction(user_validate);
</script>
Limitations
Windchill Wizard framework takes help from Windchill Action framework to pick
up the localized wizard title either from the related .rbInfo file or from a action_
<locale>.properties file. It uses the <objectType> and <action> to fetch the
required value. The problem arises when you try to use “url” attribute of
“command” tag (while defining the wizard action). If the value of the “url”
attribute points to a jsp page whose name matches with some another action, the
wizard framework will receive localized title corresponding to that action.
Consider the following scenario:
<action name="createPartWizard">
<command class=
"com.ptc.windchill.enterprise.part.forms.CreatePartFormProcessor"
method="execute" onClick="validateCreateLocation(event)"
windowType="popup"/>
</action>
"com.ptc.windchill.enterprise.part.forms.CreateMultiPartFormProcessor"
method="execute" onClick="validateCreateLocation(event)"
windowType="popup"
url="/netmarkets/jsp/part/createPartWizard.jsp?wizardType=
multiPart" />
</action>
In the above specified case, the wizard title for the action “createMultiPart”
will be picked up from the property
“part.createPartWizard.title.value” and not from the property
“part.CreateMultiPart.title.value”.
The workaround for this scenario is to use the “title” attribute of the wizard tag. If
this attribute is specified, the wizard framework will not try to look in to any
rbInfo or properties file. However, be sure that you provide a localized string as a
title to wizard tag. For example:
<%@ taglib prefix="jca" uri="http://www.ptc.com/windchill/taglib/
components"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/fmt" prefix="fmt"%>
<fmt:setBundle basename="com.ptc.windchill.enterprise.part.partResource"/
>
<fmt:message var="createMultiplePartWizardTitle" key =
"part.createMultiPart.WIZARD_LABEL" />
<jca:wizard helpSelectorKey="PartMultipleCreate"
title="${createMultiplePartWizardTitle}">
...
...
</jca:wizard>
Sample Code
Packaged Samples
• Wizard Example One on page 815
• Wizard Example Two on page 816
• Clerk Example One on page 818
Packaged Samples
This section contains information on the sample code that is provided within the
system.
Location of Example
To navigate to this example in the produce go to Customization >> Component
Catalog >> Wizard Component >> In the example section select the second “New
Wizard Description.”
Location of Example
To navigate to this example in the product, from the Navigator open
Customization ▶ Component Catalog ▶ Wizard Component ▶ New Clerk Description.
Background
If your wizard uses one of the built-in button sets, when a user clicks the Finish,
Apply, Save, or Check In button to submit the form, a javascript function is called
that invokes the processRequest() method of the ActionController.
The WizardServlet loads the HTTP form data and other wizard context
information, such as where the wizard was launched, into a NmCommandBean. It
then passes the NmCommandBean to the FormDispatcher class. The
FormDispatcher calls the FormProcessorController.
The FormProcessorController partitions the form data into
ObjectBeans. One ObjectBean is created for each target object of the
wizard. It contains all the form data specific to that object and any form data that
is common to all objects. The FormProcessorController then passes the
ObjectBeans to classes called ObjectFormProcessors that perform the
tasks appropriate to the wizard — for example, creating a new object in the
database, updating an object in the database, or checking in an object
ObjectFormProcessors, in turn, can call classes called
ObjectFormProcessorDelegates to perform one or more subtasks.
If your wizard is performing an operation on a single object you may need to
create your own ObjectFormProcessor and/or
ObjectFormProcessorDelegates to perform the tasks specific to your
wizard. However, if your wizard is creating or editing an object, you may be able
to take advantage of some processors that are delivered with the product for those
purposes.
See Building Wizards to Create a Single Object on page 844 and Building
Wizards to Edit a Single Object on page 866 for more information.
If your wizard has multiple target objects you may or may not also need to create
your own FormProcessorController to control the order in which objects
are processed.
Scope/Applicability/Assumptions
Assumes that you have already created the necessary JSPs, data utilities, GUI
components, and renderers to display your wizard. Also assumes that you have
created the necessary actions to hook up your wizard to the UI.
Solution
Use the JSP client architecture framework and common components to process
wizard form data and perform the appropriate database tasks for one or more
object(s).
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Java programming
• Basic web development using HTML forms
• Familiarity with the Windchill service APIs or other APIs necessary to
perform the tasks appropriate to the wizard
Definition of terms used in this section:
Term Definition
target object Object(s) for which you are gathering data in your wizard. Some
operation(s) will typically be performed on these objects in your
wizard processing.
Solution Elements
Element Type Description
ActionController Java class This is the class to which wizard
form data gets posted and which
sends the response page sent back
to the browser after processing
completes.
Runtime location:
<Windchill>/srclib/
CommonComponents-web.jar
FormProcessor Java interface Classes implementing this interface
Controller instantiate and call
ObjectFormProcessor(s) to execute
wizard tasks.
Runtime location:
<Windchill>/srclib/
CommonComponents.jar
DefaultForm Java class A default implementation of
ProcessorController FormProcessorController that
The relationship between the main Java classes in the wizard processing
framework is shown in the UML diagram below.
Note
Wizard step validators are invoked when the user navigates wizard steps. To
prepare the object on which the validation must be performed, the
preprocess() method of the ObjectFormProcessor and
ObjectFormProcessorDelegate classes will be executed.
Not every wizard will have tasks in every phase, so it is not necessary that every
processor and every delegate implement all of these methods, if they extend from
the default classes DefaultObjectFormProcessor and
DefaultObjectFormProcessorDelegate, respectively. Those parent
classes provide default implementations of each method. If an
ObjectFormProcessor does implement one of these methods, it should call
the super() method of the DefaultObjectFormProcessor, which will
handle the calling of ObjectFormProcessorDelegates.
The HTML form data will be passed to ObjectFormProcessors and
ObjectFormProcessorDelegates in a list of ObjectBeans. An
ObjectBean contains the data specific to one target object and the data common
to all the target objects. For wizards with a single target object the list will contain
only one ObjectBean. For wizards with multiple target objects the list will
contain one ObjectBean for each target object and the ObjectBeans may be
organized into a tree structure representative of the relationship between the
objects and the order in which they should be processed. The creation of
ObjectBeans is handled by the FormProcessorController.
The FormProcessorController also handles the opening, closing, and, if
necessary, rollback of the database transaction and the calling of the
ObjectFormProcessors. For the latter, the
DefaultFormProcessorController uses objects called
ProcessorBeans. Target objects with the same parent object, which are of the
same type, and which have the same ObjectFormProcessorDelegates are
placed into the same ProcessorBean.
Each ProcessorBean also will have its own instances of the
ObjectFormProcessor and ObjectFormProcessorDelegates for the
ObjectBeans it contains. ProcessorBeans may be organized into a tree
structure to control the order in which objects are processed. (Wizards with a
single target object will have only one ProcessorBean. )
Note
ObjectFormProcessors should not open/commit additional transaction
blocks in steps 3 or 4 as nesting of transactions is not recommended.
The object handle for each row will be based on the row’s OID.
objectHandle =
CreateAndEditWizBean.getNewObjectHandle(next.getOid().toString());
• Where all the data on a given wizard step is for the same object, you specify
the object handle for that object on the wizard step action:
<jca:wizardStep action="setContextWizStep" type="object"
objectHandle="<your object handle string>" …
If data on the wizard step is common to all objects created, no object handle is
needed on the input fields. The object handle associated to the data in an
ObjectBean can be accessed by the ObjectBean.getObjectHandle()
method. The FormProcessorController controls the order in which
processors are called to process the ObjectBeans, as described in the sections
below. Note that in the illustrations below, circles are used to represent
ObjectBeans. Circles representing objects of the same type will have the same
shading.
An example of such a wizard is that in which you can create multiple parts. This
wizard has three steps:
1. Define Part
User enters the type of parts to be created and other attributes common to all
the parts being created.
2. Set Attributes
User enters the name and number of each part to be created in tabular format.
This table is dynamic in that the user can enter any number of parts.
3. Set Additional Attributes
User enters some additional attributes common to all of the parts.
The change notice ObjectBean has three child ObjectBeans. The change
task ObjectBeans have a parent ObjectBean and no children.
In this case, you would need to write your own FormProcessorController
to create the structure of ObjectBeans. This can be a subclass of the
DefaultFormProcessorController.
The default controller will create the ObjectBeans for you. You would override
its createObjectBeanStructure() method, which is given a flat list of all
the ObjectBeans. In that method you would set the parents and children of the
ObjectBeans. You pass back a list of all the root ObjectBeans. After you
have created the ObjectBean structure, the
In the diagram above the circles represent the ObjectBeans and the solid lines
the relationships between them. The rectangles represent the two
ProcessorBeans and the dotted line the relationship between them.
Each ProcessorBean will have its own instances of the
ObjectFormProcessor and the ObjectFormProcessorDelegates
needed for the objects in it. If the processor for the root ProcessorBean is
called "ProcessorInstance1" and the processor for the child
ProcessorBean is called "ProcessorInstance2", the processor methods
would be called as follows:
Method Task Performed
1 ProcessorInstance1.preProcess create an instance of a
(ObjectBean in Processor Bean 1) WTChangeOrder2 and store it in the
"object" attribute of the bean
2 ProcessorInstance2.preProcess create three instances of
(ObjectBeans in Processor Bean 2) WTChangeActivity2 and store them
in the "object" attributes of the beans
3 ProcessorInstance1.doOperation persist the WTChangeOrder2
(ObjectBean in Processor Bean 1)
4 ProcessorInstance2.doOperation persist the WTChangeActivity2
(ObjectBeans in Processor Bean 2) instances
5 ProcessorInstance1.postProcess create the associations between the
(ObjectBean in Processor Bean 1) change notice and the change tasks
6 ProcessorInstance2.postProcess none
(ObjectBeans in Processor Bean 2)
The tasks could be arranged differently. For example, you could create the
associations in method 6 instead of method 5 with the same effect. Or, you could
create an ObjectFormProcessorDelegate to create the associations in its
postProcess() method. The framework offers the flexibility to modularize
your code as best fits your wizard. Just be sure to arrange your tasks correctly
relative to the start and end of the main transaction.
Your structure of ObjectBeans could be more complex. For example:
As you can see from the diagram above, ObjectBeans will be placed in
different ProcessorBeans if any of the following is true:
• the object in the ObjectBeans are different types
• the ObjectBeans have a different ObjectFormProcessor
(Note: at this time all the ObjectBeans in the wizard must have the same
ObjectFormProcessor.)
windowType="popup" />
</action>
class="com.ptc.windchill.enterprise.attachments.forms.Second
aryAttachmentsSubFormProcessor" windowType="wizard_
step"/>
</action>
Specify the processor class for the wizard on the wizard action
The same as for a wizard with a single target object. See Specify the processor
class for the wizard on the wizard action on page 838.
if(added_new_rows.length > 0) {
clearActionFormData();
Ext.ComponentMgr.onAvailable('checkedout.work.table',
PTC.wip.addCheckoutTableListeners);
if(added_new_rows.length > 0) {
clearActionFormData();
PTC.onAvailable('checkedout.work.table',
PTC.wip.addCheckoutTableListeners);
Limitations
• Only one ObjectFormProcessor class per wizard is supported at this
time
• The framework does not support having data for multiple objects in the same
wizard step unless it is in tabular format. It also does not support having data
common to all the objects on the same step as object-specific data.
Background
Windchill provides a framework for creating wizards and navigating between
wizard steps. It also provides data utilities, GUI components, renderers, and
validators for creating input elements in your wizard JSPs. Finally, it provides a
framework for processing the data sent to the server when the wizard form is
submitted. These frameworks and components are described in other documents
listed in the section Prerequisite Knowledge.
Scope/Applicability/Assumptions
Assume you have created a custom Windchill business object class or subtype and
you want to develop a wizard that will allow users to create one instance of that
object type in the database.
The object to be created should be a Persistable. It may or may not implement the
Typed, Foldered, and/or Iterated interfaces. Where this document makes reference
to attributes that are not applicable to your object type it is correct to ignore those
implementation details.
This document describes the creation of a very basic wizard to create objects.
There are many reusable steps available to you out of the box. For more details on
adding these steps to a wizard see Customizing Reusable Wizard Steps on page
879.
Be aware that it may not be necessary to develop your own custom wizard to
create instances of a custom type. If your type is a Windchill business class for
which a wizard with a type picker is already available, it may be possible to use
the out-of-the-box wizard for the type. The out-of-the-box wizards will
automatically find subclasses and subtypes of a given base type such as WTPart or
You need to specify any non association attributes you have defined for your sub
type in the Type and Attribute Management utility Layout for them to appear as
Input fields in the non driver attributes table. Attributes will be displayed in the UI
exactly as you specify them in the Type and Attribute Management utility.
If you want to order the attributes on this step differently, you will need to create a
new jsp for this step specifically for your subtype but you can still use the New
Part wizard.
However, if you need to associate other objects to your new object or require
additional wizard steps, you will likely need to develop a custom wizard.
This document describes the process of developing a wizard that creates a single
object. See Building Wizards to Edit a Single Object on page 866, for information
on constructing a wizard to edit an object.
Intended Outcome
Add a single- or multi-step HTML wizard to the product that allows a user to
create a business object in the database. The arrangement of steps and presentation
of attributes within the wizard should be similar to that of other Windchill wizards
to provide a consistent user experience.
Solution
Use common jsp, tag, JavaScript, and Java class components built on top of the
jsp wizard framework to create a wizard for capturing user input and for
processing that input and creating the object in the database.
Note
If you follow the standard naming convention for actions and place your jsp in
the <objecttype>\<actionname>.jsp location you do not need the url parameter.
The pretend object types for the examples do not follow that in order to avoid
cluttering your system.
We recommend that you name your action (and main wizard jsp file) “create.” If
you will have more than one create action for your objecttype based on launch
point or other criteria, you can add a suffix to the action name to qualify it, as
shown below:
createFrom<launch point>
Example: createFromWorkspace
create<type of object>
Example: createSharedDocument
Add this action to an action model so that you can access it on your system.
<%@include file="/netmarkets/jsp/util/end.jspf"%>
At this point you have created a simple wizard and when you launch it you should
see:
You can now develop your own jsp files for your unique steps using the same
table, property panel, and javascript components used in the jsp files for common
steps.
<%@include file="/netmarkets/jsp/util/end.jspf"%>
Note
For the defineItemAttributesWizStep we also had to include the initializeItem
tag to setup the type we are creating. For more details on this tag and on the
other options available when using this step see Customizing Reusable Wizard
Steps on page 879.
At this point your wizard can create FakeLiterature objects. There are many
variations on this basic setup. For more information see the customizations below,
the sample code below, the Wizard Processing on page 819 and Customizing
Reusable Wizard Steps on page 879.
If you create your own processor, be aware that its preProcess() method will be
called by the standard validator classes after each wizard step. Make sure you do
not modify the database in this method.
Here are some of the more common cases where you may need to write your own
ObjectFormProcessor class and the methods you would override to handle them:
Note that if your wizard is launched from a table and you have specified “ajax=
”row”” on the wizard action, you must set the refreshInfo attribute on the
FormResult to tell the system what rows to refresh. Typically, the attributes of the
DynamicRefreshInfo object will be as follows:
action = NmCommandBean.DYNAMIC_ADD
oid = the NmOid of the object that was created
location = the NmOid of the table object containing the new row. Typically, this
will be a folder.
If you have used an ajax attribute of “page” or “component” you do not need to
set the refreshInfo attribute.
See the Customizing the UI with Ajax on page 277 section in the Customizing
HTML Clients Using the Windchill JSP Framework on page 276 chapter and the
javadoc for the FormResult and FormProcessingStatus classes for more
information.
try
{
< persist the object >
}
catch(WTException e)
{
< do error handling >
Note that delegates are called after form processor tasks in most processing
phases, but in the doOperation phase they should be called before the form
processor does its tasks. This is to allow delegates to perform operations after all
attributes have been set but before the object is persisted.
if (!continueProcessing(preProcessResult)) {
return preProcessResult;
}
Note that the above example is written so that the processor could be used for
wizards creating more than one object.
In general, it is probably preferable to use the delegate approach for setting your
attributes rather than the subclass approach as it will insulate you from any
modifications that might be made to the CreateObjectFormProcessor preprocess()
method in the future.
Limitations
When laying out the steps and attributes of a Windchill object creation wizard, it
is important to keep in mind the interdependencies between the object type,
container context, organization context, folder location, default life cycle, and,
possibly, other attributes of your new object. These interdependencies can result
from:
• type definitions
• object initialization rules (OIRs)
• access control policies (ACLs)
Type Definitions
Many wizards allow a user to create one of several object subtypes derived from a
given base type. You can define soft subtypes and global attributes in the Attribute
and Type and Attribute Management utility at the organization or site level. This
means that the organization container of the object must be known before the list
of available object types is displayed and the input fields for global attributes are
rendered. Also, the default type for some Windchill business types is determined
by preferences which can be set at the container, organization, and site levels so
these must also be known
As you can see from this diagram, the relationships between various object
properties can become complex and circular. For example, to display an input
field for folder location you must know the default folder set by the OIR, which
requires knowledge of the type of object being created. However, to display a
picker with the available object types you must know the administrative domain,
which is determined by the folder.
Sample Code
<script src='netmarkets/javascript/baseline/baseline.js'></script>
<jca:initializeItem operation="${createBean.create}"
baseTypeName="wt.vc.baseline.ManagedBaseline"/>
<jca:wizard buttonList="NoStepsWizardButtons"
helpSelectorKey="baseline.createHelp">
<jca:wizardStep action="setBaselineAttributesStep"
type="baseline" />
%@include file="/netmarkets/jsp/util/end.jspf"%
<fmt:setBundle
basename="com.ptc.windchill.enterprise.product.productResourceClie
nt"/>
<jca:initializeItem operation="${createBean.create}"
baseTypeName="wt.pdmlink.PDMLinkProduct"
<jca:wizard helpSelectorKey="PDMAdminProdCreate_Help"
buttonList="DefaultWizardButtonsNoApply">
</jca:wizard>
<SCRIPT language="javascript">
.
.
.
</SCRIPT>
Location of Example
To navigate to this example in the produce go to Customization ▶ Component
Catalog ▶ Wizard ▶ Wizard Component ▶ Examples ▶ Basic Create Wizard.
Background
Object edit wizards are typically launched by an action labeled “Edit” or “Check
Out and Edit.”
Developing a wizard to edit a business object is very similar to developing a
wizard to create that business object. Many of the components you will use are the
same. However, there are a few differences between create and edit wizards and
some of these require different components or different component configuration.
These differences include the following:
• Edit wizards do not allow users to change the container context, owning
organization, folder location, or type of an object
• Some edit wizards do not allow the user to change the identity attributes on the
master of an object (for example: name and/or number). Such changes must be
made via a Rename or Edit Common Attributes client. Other master attributes
may not be editable also.
• If the object being edited is a Workable and it is not checked out by the user
when the edit wizard is launched, the wizard should check out the object
automatically.
• The attribute input fields in edit wizards are pre-populated with the values that
exist in the database for the object rather than the default values defined in the
Java class or Attribute and Type and Attribute Management utility.
• Edit wizards for Workables have different navigation buttons. Instead of an
OK button they have Save and Check In buttons. The former saves the
changes to the working copy of the object without checking in or iterating it.
The second creates and checks in a new iteration of the object. Also, the
Cancel button pops up a message reminding the user that the object will
remain checked out.
Components available specifically for editing include:
• jsp and jspf files for wizard steps that are common to multiple wizards
• custom HTML tags for managing wizard data and displaying elements on the
page
• Java classes for processing the wizard data after the user submits the wizard
Intended Outcome
Add a single- or multi-step HTML wizard to the product that allows a user to
update a business object in the database. The arrangement of steps and
presentation of attributes within the wizard should be similar to that of other
Windchill wizards to provide a consistent user experience.
Solution
Use common jsp, tag, JavaScript, and Java class components built on top of the
jsp wizard framework to create a wizard for capturing user input and for
processing that input and creating the object in the database.
Solution Elements
Element Type Description
Tags
Note
All of the tags in the "Solution Elements" section of the Building a Wizard to
Create a Single Object on page 844 topic are also applicable to edit wizards.
This tag is in addition to those.
See the section "Solution Elements"Building Wizards to Create a Single
Object on page 844 for more information.
autoCheckOutItem Tag Checks out the object to the current user if
it is not already checked out. Adds an
object reference to the working copy as an
attribute of the current HTTPRequest, as a
parameter in HTTPRequestData parameter
map of the NmCommandBean, and as a
hidden field in the DOM. The key to the
working copy value is
CreateAndEditWizBean.WORKING_COP
Y_REF_PARAMETER_NAME.
This tag should be put in the main JSP for
the wizard immediately below the
initializeItem tag.
Tag library: <Windchill>/codebase/WEB-
INF/tlds/wo rkinprogress.tld
Tag handler: com.ptc.windchill.enterprise.
wip.tags.Auto CheckOutObjectTag
Beans
CreateAndEditWizBean Java class This bean is available to your jsps if you
include the includeWizBean jspf file. It has
getter methods for wizard data such as the
operation (create or edit) and working copy
object reference.
Java Classes You can use the classes below to help
create and process your wizard. They are
located in the <Windchill>/codebase/WEB-
It is recommended that the action (and main wizard jsp file) be named “edit.” If
there will be more than one edit action for the objecttype based on launch point or
other criteria, add a suffix to the action name to qualify it, as shown below:
editFrom<launch page or table> Ex: editFromAttributesTable
edit<name for a subset of attributes Ex: editAnnotations
being edited>
Add this action to an action model so that it can be accessed it on the Windchill
system.
AutoCheckOutItem Tag
If your target object is a Workable and your wizard can be launched for an object
that is not already checked out via a “Check Out and Edit” or other action, you
should include an autoCheckOutItem tag in your main jsp immediately below
the initializeItemTag.
<%@ taglib prefix="wip"
uri="http://www.ptc.com/windchill/taglib/workinprogress"%>
...
<wip:autoCheckOutItem/>
This tag will check out the object to the current user before opening the wizard.
Button Set
Typically, wizards for editing Workable objects will use one of the following two
button sets:
• “EditWizardButtons” (multiple-step wizards)
• “NoStepsEditWizardButtons” (single step wizards)
These include Save and Check In buttons.
For editing nonWorkable objects one of the following is usually used:
• DefaultWizardButtonsNoApply (multiple-step wizards)
• NoStepsWizardButtons (single step wizards)
These are all defined in <Windchill>/codebase/config/actions/
actionmodels.xml.
doOperation() method
• calls super.doOperation() to call the doOperation() methods of
any FormProcessorDelegates registered for the wizard
• calls PersistenceHelper.manager.save() to store the Persistable in
the database
The setResultNextAction() method is deprecated. Instead, the
FormProcessor should return a list of the Oids that were affected by the action
(if any), and let the components displayed in the UI request updates from the
server, as necessary.
If you are extending an existing Windchill business class, there may be a
processor specific to that class that you should use or extend instead of the
DefaultEditFormProcessor or EditWorkableFormProcessor.
These are shown in the table below. Consult the javadoc for these classes for more
information on their behavior.
If your class Use processor class
extents
WTChangeIssue com.ptc.windchill.enterprise.change2.forms.processors.Ed
itProblemReportFormProcessor
WTChangeRequest2 com.ptc.windchill.enterprise.change2.forms.processors.Ed
itChangeRequestFormProcessor
WTChangeOrder2 com.ptc.windchill.enterprise.change2.forms.processors.Ed
itChangeNoticeFormProcessor
WTChangeActivity2 com.ptc.windchill.enterprise.change2.forms.processors.Ed
itChangeTaskFormProcessor
WTVariance com.ptc.windchill.enterprise.change2.forms.processors.Ed
itVarianceFormProcessor
If one of the provided form processors meets your needs, you do not need to write
your own processor — just specify that processor as the value of the class attribute
of the command subtag of your wizard action. If they do not meet your needs, you
should write a subclass of one of them to process the wizard form data. See
"Creating Your Form Processor and Form Processor Delegates" section in
Building Wizards to Create a Single Object on page 844, for examples of cases
where you may need to implement your own processor.netmarkets/
jsp/components/beginWizard.jspf
Sample Code
<fmt:message var="attributeStepLabel"
key="product.editProductAttributesWizStep.title" />
<jca:initializeItem operation="${createBean.edit}"/>
<jca:wizard buttonList="NoStepsWizardButtons"
helpSelectorKey="PDMAdminProdEdit_help">
<%-->
This step uses the common action definition. The JSP file for
the step is, however, product-specific and hooked up using
PartManagement-typedservices-properties.xconf
<--%>
<jca:wizardStep action="editAttributesWizStep" type="object"
label="${attributeStepLabel}"/>
</jca:wizard>
<%-->
PartHelper.js contains the “onloadEditPartWizard” method
<--%>
<script language="JavaScript"
src="netmarkets/javascript/part/PartHelper.js"></script>
<% if(InstalledProperties.isInstalled(InstalledProperties.SCMI)) {
%>
<attachments:fileSelectionAndUploadApplet
forceApplet='${param.addAttachments != null }'/>
<% } %>
<--%>
<script language="Javascript">
</script>
<fmt:setBundle
basename="com.ptc.windchill.enterprise.part.partResource"/>
<fmt:message var="editAttributesWizStepLabel"
key="part.createPartWizard.SET_ATTRIBUTES_WIZ_STEP_LABEL" />
<fmt:message var="attachmentsWizStepLabel"
key="part.createPartWizard.ATTACHMENTS_WIZ_STEP_LABEL" />
<jca:initializeItem operation="${createBean.edit}"/>
<wip:autoCheckOutItem/>
<% } %>
<script
language="Javascript">newOrCheckedOutInWorkspace=true</script>
<% } %>
<% if (InstalledProperties.isInstalled(InstalledProperties.SCMI) ||
InstalledProperties.isInstalled(InstalledProperties.PARTSLINK))
{ %>
<% } %>
<jca:wizard buttonList="${buttonSet}"
helpSelectorKey="PartEdit_help">
<%-->
The Set Attributes step uses the common action definition. The JSP
file for the
step is, however, part
specific and hooked up using PartManagement-typedservices-
properties.xconf
<--%>
<jca:wizardStep action="editAttributesWizStep"
label="${editAttributesWizStepLabel}" type="object"/>
<%-->
<--%>
<jca:wizardStep action="attachments_step"
label="${attachmentsWizStepLabel}" type="attachments" />
</jca:wizard>
<%@include file="/netmarkets/jsp/util/end.jspf"%>
Additional Resources
Packaged Samples
This section contains information on the sample code that is provided within the
system.
Background
Windchill provides many reusable wizard steps that can be configured and added
to a custom wizard.
In many cases reusing a wizard step is as simple as adding the correct wizard step
tag specifying the wizard step action to your wizard tag. This document is not
intended to cover this simplest case. In some cases there can be additional
information required by a step or additional customizations you may want to do
on a step. This document describes a few available reusable steps that have some
additional required information or customization options. This section details
when and how to use these steps.
Scope/Applicability/Assumptions
Assume you have created a custom Windchill business object class or subtype and
you want to develop a wizard that will allow users to create or edit one instance of
that object type in the database.
This document describes common wizard steps that are available for reuse.
Additionally, if your custom type extends an existing Windchill business class,
such as WTPart, WTDocument, or WTChangeIssue, there may be
components more specific to those classes that could or should be used instead of
Intended Outcome
Add a preexisting step to the new wizard and configure the step.
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
• The Windchill framework for creating wizards, creating custom wizard steps,
and processing wizard data. For more information see:
○ Building Wizards to Create a Single Object on page 844
Building Wizards to Edit a Single Object on page 866
These topics have multiple prerequisites of their own which you should also study.
This document will build on this knowledge and provide additional information
on the components available to help you create and process wizards for the
specific purpose of creating a Windchill business object in the database.
defineItemAttributesWizStep
The body of this step typically contains four sections: a read-only context property
panel, a type picker, and a driver attributes property panel and the editable
attributes panel. It is configured using MVC framework and jsps. An MVC
builder defines the content of and configures the (non-driver) attributes panel in
the step. The context panel, type picker, driver attributes panel, primary content
panel (if any), and other components are configured via jsps. Only the type picker
is required.
• Context panel
editAttributesWizStep
This step is common to almost all edit wizards and is where the user edits most of
the object’s attributes. It generally contains a read-only context property panel and
an attribute input panel.
By default there are no read only attributes. The desired attributes vary by object
type. An MVC builder is used to configure the set of read only attributes to be
displayed foa given type when it is desired. Some typical attributes displayed in
the read only are are:
• the object type
• the container name (If the object is WTContained)
• the organization id (If the new object is OrganizationOwned and the
preference Display -> Expose Organization is set to true)
You will need to decide what, if any, information needs to be displayed in this
panel for your object type.
The attribute input panel typically contains input fields for all the editable soft and
hard attributes for the object type, it does not contain input fields for part
classification attributes. These are entered on a following step. The set of
attributes displayed in this panel is controlled by the Type and Attribute
Management utility.
Solution
Add the editAttributesWizStep to your new wizard and configure the step.
Action
<action name="editAttributesWizStep" id="editAttributesWizStep"
preloadWizardPage="false"
required="true" afterVK="editAttributes"
resourceBundle=
"com.ptc.core.ui.componentRB">
<component name="editAttributesWizStep" typeBased="true"
windowType="wizard_step"/>
</action>
Action file: <Windchill>/codebase/config/actions/actions.xml
Note that the editAttributesWizStep action specifies the page as non-preloaded in
case in is not the first step in the wizard and is dependent on an earlier step.
However, if it is the first step, the framework will preload it regardless of how it is
specified on the action.
JSP
View JSP Page: <Windchill>/codebase/netmarkets/jsp/object/
propertyAttributesWizStep.jsp
Validator
The EditAttributesStepValidator is available to validate the data entered in this
step. This class will validate whether or not all the input attributes in the edit
attributes step have valid values by checking constraints. The "required" attribute
validation will be done on the client with javascript.
Customization
attrPanel.addComponent(factory.newAttributeConfig(DescriptorConstants.
ColumnIdentifiers.TYPE));
return attrPanel;
}
}
Solution
Add the SetContextWizStep to your new wizard and configure the step.
Solution Elements
Action
<action name="setContextWizStep" id="setContextWizStep"
preloadWizardPage="true"
required="true"
afterVK="setContextWizStep">
<command windowType="wizard_step"/>
</action>
Action file: <Windchill>/codebase/config/actions/actions.xml
JSP
View jsp page: <Windchill>/codebase/WEB-INF/jsp/netmarkets/
object/setContextWizStep.jsp
Validator
The ContextWizardStepValidator is available to validate the data in the set context
wizard step. The ContextWizardStepValidator just validates that the form data
contains a valid container object reference.
This validator also determines if the step should be displayed in the wizard. If the
context has been determined from the launch point the step will be skipped even
though it is included in the wizard.
Customizations
setClassificationAttributesWizStep
Solution
Add the setClassificationAttributesWizStep to your new wizard
and configure the step.
Solution Elements
defineItemAttributesWizStep
The body of this step typically contains four sections: a read-only context property
panel, a type picker, and a driver attributes property panel and the editable
attributes panel. It is configured using MVC framework and jsps. An MVC
builder defines the content of and configures the (non-driver) attributes panel in
the step. The context panel, type picker, driver attributes panel, primary content
panel (if any), and other components are configured via jsps. Only the type picker
is required.
Note that one of the attributes typically presented in this list is folder location.
Folder location drives administrative domain which, in turn, drives access
control policies which, in turn, drives the list of object types available for
creation by the user. The list of types presented in the type picker is based on a
default folder derived from the launch context. The user could potentially
select a different folder location for which the access control policies vary.
Thus it is possible the user could select a folder for which they do not have
permission to create the selected type. If this happens, an error message will
be displayed when the user clicks OK.
• Checkboxes
This section contains checkboxes to provide processing instructions for the
new object. These include:
Checkbox label Applicability Description
Keep checked out Used for new If checked, the system
RevisionControlled checks out the object
objects after creation
Checkout and download Used for creating If checked, the new
documents from document is checked out
templates and downloaded
Enabled Used for creating If checked, the new
document templates template is immediately
available for use
Solution
Add the defineItemAttributesWizStep to the new wizard and correctly
configure the step.
When to use this step This step is intended for use for creating Typed objects. For
Edit Wizards see editAttributesWizStep.
Action
The action for this step is:
<action name="defineItemAttributesWizStep" afterVK=
"setAttributesWizStep"
id="defineItemAttributesWizStep " preloadWizardPage="false"
required="true"
resourceBundle="com.ptc.core.ui.componentRB">
<component name=" defineItemAttributesWizStep"
typeBased="true" indowType="wizard_step"/>
</action>
Action file: <Windchill>/codebase/config/actions/actions.xml
Note
The action for this step has a component attribute instead of a command
attribute because it is created using a MVC builder Java class.
JSPs
View jsp page: <Windchill>/codebase/WEB-INF/jsp/netmarkets/
object/defineItemAttributesWizStep.jsp
This is the default JSP that defines the view for this step. This view includes a
read-only property panel for the context name, a type picker, the driver attributes
panel and the editable attributes panel for entering attribute values.
The OOTB view jsp includes other jsps that do some of the work. The table below
describes these sub-jsps
JSP Description
defineItemAttributesWizStep.jsp The view jsp for the Set Attributes step;
includes configureTypePicker tag for
presenting & configuring the type
picker, the driver attribures panel,
Primary Content Panel (if any), the
attribute table and check boxes(if
applicable).
defineItemReadOnlyPropertyPanel.jspf Contains the describePropertyPanel tag
for the read-only panel
defineItemReadOnlyProperties.jspf Contains describeProperty tags for the
attributes in the read-only panel
defineItem.jspf Looks up the JSP for the driver
Tags
All the tags below are defined in the <Windchill>/codebase/WEB-INF/
tlds/components.tld file.
See the javadoc for the Windchill Client Architecture Common Components tag
library and the javadoc for the tag handlers listed below for more information on
the tags and their attributes.
Customizations
If the Set Attributes step is the first step in the wizard or nothing in this step is
affected by data on prior steps then it can be preloaded. Otherwise, specify it to
not be preloaded in the step action. If the wizard has a Set Context step and a type
picker, it should not be preloaded as the context will affect the content of the type
picker.
Note
Please remember that you should always place your custom jsp and jspf files
in a directory under wtSafeArea, as described in Managing Customizations on
page 109.
For all other wizards, the base type is used as the default type.
When the user selects a type in the type picker, javascript is executed that
refreshes the driver attributes panel below it and all following wizard steps. This is
necessary because object type can affect which jsps are used for subsequent steps
as well as the attribute input fields displayed.
editAttributesWizStep
This step is common to almost all edit wizards and is where the user edits most of
the object’s attributes. It generally contains a read-only context property panel and
an attribute input panel.
By default there are no read only attributes. The desired attributes vary by object
type. An MVC builder is used to configure the set of read only attributes to be
displayed foa given type when it is desired. Some typical attributes displayed in
the read only are are:
• the object type
• the container name (If the object is WTContained)
• the organization id (If the new object is OrganizationOwned and the
preference Display -> Expose Organization is set to true)
You will need to decide what, if any, information needs to be displayed in this
panel for your object type.
The attribute input panel typically contains input fields for all the editable soft and
hard attributes for the object type, it does not contain input fields for part
classification attributes. These are entered on a following step. The set of
attributes displayed in this panel is controlled by the Type and Attribute
Management utility.
Solution
Add the editAttributesWizStep to your new wizard and configure the step.
Action
<action name="editAttributesWizStep" id="editAttributesWizStep"
preloadWizardPage="false"
required="true" afterVK="editAttributes"
resourceBundle=
"com.ptc.core.ui.componentRB">
<component name="editAttributesWizStep" typeBased="true"
windowType="wizard_step"/>
</action>
Action file: <Windchill>/codebase/config/actions/actions.xml
Note that the editAttributesWizStep action specifies the page as non-preloaded in
case in is not the first step in the wizard and is dependent on an earlier step.
However, if it is the first step, the framework will preload it regardless of how it is
specified on the action.
JSP
View JSP Page: <Windchill>/codebase/netmarkets/jsp/object/
propertyAttributesWizStep.jsp
Validator
The EditAttributesStepValidator is available to validate the data entered in this
step. This class will validate whether or not all the input attributes in the edit
attributes step have valid values by checking constraints. The "required" attribute
validation will be done on the client with javascript.
attrPanel.addComponent(factory.newAttributeConfig(DescriptorConstants.
ColumnIdentifiers.TYPE));
return attrPanel;
}
}
SetContextWizStep
This step typically has only one input field, which is a picker for the owning
container of the object being created. The selected container will be used to select
the appropriate OIRs for other attributes.
Solution
Add the SetContextWizStep to your new wizard and configure the step.
Solution Elements
Action
<action name="setContextWizStep" id="setContextWizStep"
preloadWizardPage="true"
required="true"
afterVK="setContextWizStep">
<command windowType="wizard_step"/>
</action>
Action file: <Windchill>/codebase/config/actions/actions.xml
JSP
View jsp page: <Windchill>/codebase/WEB-INF/jsp/netmarkets/
object/setContextWizStep.jsp
Validator
The ContextWizardStepValidator is available to validate the data in the set context
wizard step. The ContextWizardStepValidator just validates that the form data
contains a valid container object reference.
This validator also determines if the step should be displayed in the wizard. If the
context has been determined from the launch point the step will be skipped even
though it is included in the wizard.
setClassificationAttributesWizStep
Solution
Add the setClassificationAttributesWizStep to your new wizard
and configure the step.
Solution Elements
Action
<action name="setClassificationAttributesWizStep"
id="setClassificationAttributesWizStep"
hidden="true" required="true" preloadWizardPage="false">
<command windowType="wizard_step"/>
</action>
Action file: <Windchill>/codebase/config/actions/
PartManagement-actions.xml
JSP
View JSP Page: <Windchill>/codebase/netmarkets/jsp/part/
setClassificationAttributesWizStep.jsp
Validator
The Set Classification Attributes step uses the same validator as the Set Attributes
step.
Customizations
attachments_step
This step is typically included when creating or editing objects that are
ContentHolders. It allows the user to attach documents, links, and other content to
the new object.
See Attachments on page 322 for information on the elements that must be
included to incorporate this step.
No validator is provided or needed for the attachments step.
setAccessControlWizStep
This step is typically included when you want to allow the user to make
modifications to the access permissions for the object.
See Component Access Control on page 316 for information on the elements that
must be included to incorporate this step.
Sample Code
//The driver attribute panel that defines the top section that
includes the read
Default view JSP for the Set Attributes Step for WTPart
WTPart need to include a customized type picker, ReadOnlyPropertyPanel, and
custom information related to the CreateCadDocStep option. Hence we need to
define a builder for WTPart(PartDefineItemAttributesWizStepBuilder) to set the
view for the Set Attributes step (WEB_INF/jsp/part/
defineItemAttributesWizStep.jsp).
The only difference from the Generic one is that the jsps to render the driver
attributes is different.
<%@ taglib uri="http://www.ptc.com/windchill/taglib/jcaMvc"
prefix="mvc"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/mvc" prefix=
"mvc1"%>
<%@ include file="/netmarkets/jsp/components/beginWizard.jspf"%>
<%@ include file="/netmarkets/jsp/components/createEditUIText.
jspf"%>
<%@ include file="/netmarkets/jsp/components/includeWizBean.jspf"%
>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/wrappers"
prefix="wrap"%>
<div id='${createBean.encodedCurrentObjectHandle}
driverAttributesPane'>
<%@ include file="/netmarkets/jsp/part/defineItem.jspf"%>
</div>
<mvc:attributesTableWizComponent/>
<br>
<c:if test='${param.invokedfrom != "workspace"}'>
<%@ include
file="/netmarkets/jsp/components/keepCheckedOutCheckbox.jspf"%>
</c:if>
JSP for the Defining the Define Item Panel for WTPart
Filename: <Windchill>/codebase/ netmarkets/jsp/part/
defineItem.jspf
This example illustrates how to override the read-only context panel and to
reconfigure the type picker.
<%@ page import="com.ptc.windchill.enterprise.part.PartConstants"
%>
<%@ page import="com.ptc.core.ui.componentRB" %>
<jca:describePropertyPanel var=
"defineItemStepContextPanelDescriptor"
id="defineItemStepContextPanelDescriptor"
scope="request" mode="VIEW" type="wt.part.WTPart">
<jca:describeProperty id="containerName"
label="${createBean.containerLabel}"/>
<%-- Get the part types to filter from type picker selection list
--%>
<partcomp:PartCreateHelper var="partTypesToFilter"
method="getPartTypesToFilter"/>
<c:choose>
<c:when test='${param.invokedfrom == "tabular_input"}' >
<jca:configureTypePicker>
<%--
Type Picker picks up the default from Preferences.
It does not have be set here.
--%>
<c:forEach var="item" items="${seedPartTypes}">
<p:pickerParam name="seedType" value="${item}"/>
</c:forEach>
<c:forEach var="item" items="${partTypesToFilter}">
<p:pickerParam name="filterType" value="${item}"/>
</c:forEach>
<p:pickerParam name="type" value="ROOT_TYPES"/>
</jca:configureTypePicker>
</c:when>
<jca:configureTypePicker>
<c:otherwise>
<jca:configureTypePicker>
<%--
Type Picker picks up the default from Preferences.
It does not have be set here.
--%>
</jca:configureTypePicker>
</c:otherwise>
</c:choose>
Additional Resources
Packaged Samples
Many out of the box Windchill wizards make use of these steps and can be
referenced as examples.
Scope/Applicability/Assumptions
In order to launch a JCA action from an external system users will need to be able
to provide login credentials to the Windchill system when prompted. Refer to the
following for more information on those tasks:
• Windchill Client Architecture Wizard on page 791
• Windchill Client Architecture Common Objects Overview on page 236 —
provides information on some common Java classes used in the UI, such as
NmCommandBean.
• Javascript Functions Overview on page 238
• Customizing the UI with Ajax on page 277
Intended Outcome
An external system POSTs a request to a Windchill MVC controller with
necessary action parameters (see the example below) which then redirects to
requested action. When object(s) on the Windchill server are created, a JSON
response containing the UFID(s) is generated and returned as a call back to the
External system.
Solution
From the external system, launch a new HTML window which makes a POST
request to the Windchill system and gets back the created objects IDs.
Prerequisite knowledge
To apply this process, you need to have an understanding of the following:
• Basic web development using HTML forms
• A user clicks a create action in the external system using registered Windchill
system using a new window from the external system.
• The URL redirects the call to the registered MVC controller which then
invokes the registered JSP and redirects the create JSP for the requested action
and object type.
• Once the Windchill object(s) is created, a JSON object is returned back to the
caller with key as “UFIDs”. The form method is “GET” the external URL will
have to read the URL query parameter.
See the example scenario below for details.
Limitations
• The operation is performed within the Windchill transaction block after the
action is invoked.
• The call back value will be based on browser support for “GET” form method.
Assumptions
1. The selected objects and the context object information are available to the
external system.
2. The user launching the URL has access to the action.
3. The input field for the context object should be encoded, a sample context
object for a container would look like
“OR%3Awt.pdmlink.PDMLinkProduct%3A38380”
Considerations
The full domain name is required for access permission to the frame window.
Replace the Windchill system URL with the full domain URL. Example, if the
server is the server is on domain ptcnet.ptc.com the URL should include :
http://windchillServer.ptcnet.ptc.com/<web-app>/ptc1/externalRequest?
oid="+contextOid+"&action=create&type=changeRequest;"
and not :
http://myserver/Windchill...
</script>
<body>
<form method="post" id="JCAActionForm"
onSubmit="return false;" target="_self">
Container Oid: <input type="text" id="contextOid"/>
External URL: <input type="text" name="externalURL"
value="http://externalHostname:port/<web-app>"/>
<input type="hidden" name="soidarray" value="OR:wt.part.
WTPart:90740___
OR:wt.part.WTPart:547106"/>
<button onclick='launchJCAAction();'>Launch Action</button>
</form>
</body>
</html>
An example UFID for the created Windchill object would look like:
“VR:wt.change2.WTChangeRequest2:188695:651462062-
1309389210495-20458805-192-14-253-
132@<windchillServer>”
Background
This information applies to any client-side generated form data, that is hidden (i.
e., not displayed in a table in the wizard). This is also known as “data store only”
data; it refers to data that exists in the data store on the client, but is not rendered
in the DOM, so it is not visible in the page.
The hidden data is generated by application-specific JavaScript logic on the client
and added as hidden input form data that is submitted to the server. It is also
possible to have hidden columns added to a table by the server-side table builder,
and then modify those values in the client-side JavaScript.
Scope/Applicability/Assumptions
• You have a wizard that contains one or more tables.
• Your code needs to add data to the form submitted by the wizard that is not
visible in UI.
• This data may originate on the client, or it may have default values provided
by the server when the table is created, and those default values are to be
manipulated by your application's client-side logic.
• There may be one or more values associated with each table appearing in the
wizard, or there may be one or more (hidden) columns associated with each
row in a table.
Intended Outcome
The wizard's form submission will include hidden data that is not visible to the
user and that has been created or modified by application-specific, client-side
logic.
Solution
The solution involves three or four application-provided parts:
1. Define hidden table columns for the tables that are to appear in the wizard and
supply default values for the cells in those columns (by associating an
appropriate data utility with those columns). You may use an existing data
utility if appropriate, but it is more likely that you will provide a new, custom,
application-specific data utility to fulfill this need.
Prerequisite Knowledge
To achieve this result, you need to understand:
• Basic development of Windchill web pages
• JavaScript
• JCA/MVC table builders
• JCA Form Processing
Note
If you do not need per-table-row hidden input values for your application, you
may skip this step.
If your application needs a hidden input value for each object appearing in a table,
add one or more column definitions in the wizard's table builder defining columns
that are 'data store only' and 'editable'. Use an appropriate data utility to generate
the default values. Give the columns unique names so they can be identified in
your event listener (e.g., “hiddenColumn1”).
TableConfig table = factory.newTableConfig();
table.setId ('MYTABLEID');
..
. <... other table configuration here ...>
.
ColumnConfig hiddenCol1 = factory.newColumnConfig
("hiddenColumn1", false);
hiddenCol1.setDataUtilityId ("SOME_DU_ID");
hiddenCol1.setNeed ("SOME_DU_ID");
hiddenCol1.setComponentMode (ComponentMode.EDIT);
hiddenCol1.setDataStoreOnly (true);
table.addComponent (hiddenCol1);
// Add submit listener for wizard table once the table becomes
'available'
PTC.onAvailable
( 'MYTABLEID', function (table)
{
table.on ('submit', PTC.MYAPPLICATION.MYLISTENER);
});
}
In this example, the submit listener is adding hidden input data to the submitted
form, using JCAappendFormHiddenInput. In this example, the client-side
logic looks for two hidden properties that have been added to each row in the table
with ID 'MYTABLEID'. Those properties exist on each row in the data-store, but
are not included in the DOM of the table that appears in the UI. These properties
are named “hiddenColumn1” and “hiddenColumn2”. If either of these
hidden properties is found on an object, a hidden input field is generated that
identifies the object [row.get (“objectHandle”)] and the hidden value itself
(“hiddenColumn1”, etc.) and which specifies a not-very-useful constant value.
The example also shows how to add a hidden input value that is not associated
with any hidden column, but still identifies a specific object (see the second call to
JCAappendFormHiddenInput, above).
Of course, this same type of listener could be used to add, change, or remove any
desired data to the form before it is submitted; it is not limited to manipulating so-
called “data store only” fields.
This results in output which will include something like the following code, which
shows the three client-side generated values that were added to the object by the
Javascript 'submit' listener shown earlier.
KEY = noColumn
VALUE = FOO_BAR_BIZ_BAZ
KEY = hiddenColumn1
VALUE = HIDDEN_COLUMN_1_GENERATED_VALUE
KEY = hiddenColumn2
VALUE = HIDDEN_COLUMN_2_GENERATED_VALUE
Limitations
This information is limited to adding hidden form data that is associated with a
specific JCA table and that is identified by a specific table ('MYTABLEID') in
the example code above). The hidden data may be defined as one or more hidden
columns in the table, in which case a unique value may be submitted for every
row in the table, or it may be associated with the table itself and not connected
with any row or column, in which case one or more values may be submitted for
the entire table. These two approaches may be combined within a single form
submission or they may be used separately.
Packaged Samples
Note
The customization utilities must be enabled to see the samples. See
Customization Tools Overview on page 381 for information on enabling the
customization utilities.
KEY = hiddenColumn1
VALUE = HIDDEN_COLUMN_1_GENERATED_VALUE
KEY = hiddenColumn2
VALUE = HIDDEN_COLUMN_2_GENERATED_VALUE
Scope/Applicability/Assumptions
This information should be applied by a developer or customizer who is
responsible for creating a information page for a new Windchill business object.
This documentation assumes that:
• You are familiar with the use of Java builder classes used to acquire the data
from the server as described in MVC Components on page 247.
• In prior releases the information was retrieved using the InfoPageBean
Java class. This is not the recommended approach any longer.
Intended Outcome
An Information Page.
The information page is made up of the following pieces, many of which are
configurable.
Title bar area:
• Go to latest link (only appears on info pages for non-latest versions)
• Actions Menu
• Commonspace/Workspace toggle
• Object Type icon
• Item Identification
• Status Glyphs (checkout, share, pending changes, etc)
• State of item (only appears for LifeCycleManaged items)
Tab Set
• Out of the box tabs and tabs configured by administrators are displayed at the
top
• • “+” tab that allows the user to add custom tabs
Information tab table of contents links to drag ‘n’ drop for rearranging the content
of the tab:
Attributes
The attributes option is intended to have the full set of attributes displayed as
panels or in a table
Solution
Create a builder Java class, which extends
DefaultInfoComponentBuilder, that will define the elements to be
rendered on the information page for a specific business object type. The layout of
the attributes is controlled by the attribute layout manager in the Type and
Attribute Management utility.
Prerequisite Knowledge
To apply this information you need to have an understanding of the following:
• The MVC framework for creating the Java builder class (see MVC
Components on page 247)
• JSP-based client architecture framework in Windchill (see Windchill Client
Architecture Overview on page 223)
• The actions framework in the Windchill client architecture (see Action
Framework for Windchill Client Architecture on page 474)
• How to manage attribute layouts using the Type and Attribute
Management utility (see Type and Attribute Management utility)
See TypeBased on page 255 in MVC Components Overview on page 248 for
more information.
Then, you would specify the tab set on the builder as follows:
InfoComponentConfigFactory f =
(InfoComponentConfigFactory)getComponentConfigFactory();
InfoConfig result = f.newInfoConfig();
result.setTabSet(“partInfoPageTabSet”);
For more information on configuring the tabs, and how to specify the content
(tables) for a particular tab, see Tab Customizations.section in this topic. For more
details about defining tabs please refer to Client Tabs on page 298.
// sets the action model for the TOC menu on the Tabs of the info
page
infoConfig.setNavBarName("third level nav package");
...
return infoConfig;
The action model for the TOC menu should contain the complete set of items that
can be added to any of the top level tabs.
The TOC menu is a replacement of the Third Level navigation toolbar items found
in prior releases:
You can add a status glyph to the information page for a particular business object
type. See Adding a Status Glyph on page 469 for more information,
If you would like to have the info page show the Workspace or Common space
toggle buttons (or any other set of buttons) for a another object type, you’ll need
to set the attribute “toggleButtonConfigs” on the infoModel object. The
attribute “toggleButtonConfigs” takes an array of button configs.
var cs_button = {
id: 'commonspace_button',
icon: 'com/ptc/windchill/uwgm/cadx/images/csUnHilite.gif',
PTC.infoPage.goTo('', params);
},
tooltip: 'toggle to commonspace'
};
var ws_button = {
id: 'workspace_button',
icon: 'com/ptc/windchill/uwgm/cadx/images/wsHilite.gif',
handler: function() {
var params = {
typeIdForTypeLookup: 'com.ptc.carambola.
customization.examples.
infoPage.Carambola',
oid: extractParamValue(getWindow().location.href,
'oid'),
csName: 'Carambola Example',
};
PTC.infoPage.goTo('', params);
},
tooltip: 'toggle to workspace'
};
Attribute Customizations
Attributes v.s. Visualization and Attributes
There is a validator attached to the “Attributes” and “Visualization and Attributes”
TOC options. That validator will hide one or the other based on the visualization
delegate that is found for the object type. So even if both actions are specified in
your TOC action model you would only see one in the UI:
<model name="defaultTOC">
<action name="primaryAttributes" type="object"/>
<action name="visualizationAndAttributes" type="object"/>
</model>
Second, make sure you’ve included the “Visualization and Attributes” option in
your TOC action model:
<model name="defaultTOC">
<action name="primaryAttributes" type="object"/>
<action name="visualizationAndAttributes" type="object"/>
</model>
You can make a custom visualization delegate if your object type doesn’t have
visualization out of the box, or if you would like to define different visualization
for your object type.
First define a custom visualization delegate with the desired html:
import
com.ptc.core.components.rendering.guicomponents.VisualizationComponent;
import com.ptc.core.components.visualization.VisualizationDelegate;
Your html should appear in the visualization section. Note, currently the
visualization html is put into a panel with a hard coded width and height of
298x202.
There are some cases where visualization is shown for a parent type but needs to
be hidden for a sub type. For example, visualization is shown for EPMDocuments
but is hidden Notes which are a subtype of EPMDocument. In this case the
visualization component can be hidden for the sub type by registering the
DefaultVisualizationDelegate for that sub type. This will hide the
“visualizationAndAttributes” action from the TOC so you should make sure the
TOC action model for the sub type includes the “primaryAttributes” action:
<model name="defaultTOC">
<action name="primaryAttributes" type="object"/>
<action name="visualizationAndAttributes" type="object"/>
</model>
To see some logging about which delegate is found and when actions are hidden/
shown by that delegate you can enable a log4j logger named com.ptc.core.
components.validators.VisualizationAndAttributesFilter.
Tab Customizations
Configure a Tab with a Default Set of Tables
You can specify a tab to have a set of tables shown by default. To do this, you will
create an action model that contains the actions for the desired default tables. For
example, the “Details” tab on the part information page may define the following
default tables:
<model name="partInfoDefaultDetails" resourceBundle=
"com.ptc.core.ui.navigationRB">
The tables won’t show up unless they are in the Table of Contents (TOC) action
model. See the section Configure the Table of Contents in this topic for more
details.
Please Client Tabs on page 298 or Defining Menus on page 523 for more
information about defining the action model.
The object type icon is controlled outside of the Information Page component. It is
configurable. For information on configuring the icon see Icon Delegates on page
693.
Sample Code
Example implementation for the InfoPageComponent
This example can be viewed in the Windchill product by navigating to
Customization -> Example Information Page. The Customization tab is hidden
out-of-the-box but can be enabled via the “Client Customization” preference
available in Site->Utilities->Preferences Manager.
This example shows an info page for an object of the new type “Carambola.”. The
Carambola object type is a simple Java class with an icon and various attributes.
The example illustrates how to:
• create a set of tabs
• define a tab customization menu (tab actions)
• define an action dropdown menu
Log4J
The following log4J loggers are available to provide you more information when
debugging your Information Page implementation:
Logger Description
com.ptc.core.components. Logs information related to the hiding
validators. and showing of the primaryAttributes
VisualizationAndAttributesFilter or visualizationAndAttributes
components. See Attributes v.s.
Visualization and Attributes
com.ptc.jca.mvc.components. Logs information related to finding the
AbstractInfoComponentBuilder context object for the information page.
com.ptc.mvc.components. Logs information related to the view
AbstractInfoConfigBuilder chosen for the information page. This
may be useful if you are trying to set a
custom view.
com.ptc.jca.mvc.controllers. Logs information related to determining
TypeBasedIncludeController whether the requested information page
is being rendered with a legacy jsp or
an MVC builder.
Log4javascript
Log4javascript is also available for debugging within the browser. You can turn
this on by adding a parameter to the end of the url. “&jsLog=PTC”. This will turn
on all the JavaScript logging. You will then see the logging information in the FF/
Chrome console or in a separate console which opens when you add the parameter
in IE browsers. The following loggers can also be turned on individually by
setting jsLog=<loggername>.
961
Configuring Pickers
Solution
Write a custom JSP page and use the Item Picker tag to display the picker.
Configure the search criteria fields to be included in the picker using the
PickerAttributes.xml file. Configure the object types and containers to be
searched using parameters on the itemPicker tag.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving HTML forms, JSP, XML.
• Picker common components
• Table common component
• View creation
Solution Elements
Element Type Description
pickerAttributes.xml XML Runtime location:
<Windchill>\codebase\picker
Attributes.xml
SearchResultsTable Xconf Runtime location:
.properties.xconf <Windchill> \codebase\com
\ptc\netmarkets\search\
SearchResultsTable.
properties.xconf
This file can be used to configure table
view definition.
Finally, pass the selector as below to the picker tag, as shown below, and the
search results table will be rendered with this view.
<wctags: itemPicker id=" customized_item_picker"
objectType="WCTYPE|wt.part.WTPart|org.r_and_d.mypart"
containerRef="<OR: wt.pdmlink.PDMLinkProduct:33707”
componentId="customizedItemPickerForSoftPart"
searchResultsViewId="wt.part.WTPart.customizedSearchView"/>
<tr>
<%-- launching organization picker--%>
<wctags: organizationPicker id="orgPicker" label="MyOrgPicker"
readOnlyPickerTextBox="false" editable="true" showSuggestion=
"true"
suggestMinChars="3"/>
</tr>
<tr>
<%-- launching context picker--%>
<wctags: contextPicker id="contextPicker" label=
"MyContextPicker"
pickerTitle="ContextPicker" />
</tr>
<tr>
<%-- launching Item picker--%>
<wctags:itemPicker id="itemPicker" label="MyItemPicker"
pickerTitle="ItemPicker"/>
</tr>
<tr>
<%-- launching Item picker with exclude sub types and access
controller --%>
<wctags:itemPicker id="CustomizedItemPicker" label=
"CustomizedItemPicker"
pickerTitle="CustomizedItemPicker"excludeSubTypes="WCTYPE|wt.doc.
WTDocument|
org.rnd.Minutes,WCTYPE|wt.doc.WTDocument|org.rnd.General"
customAccessController="com.ptc.windchill.
enterprise.search.server.LatestVersionAccessController"/>
</tr>
<tr>
<%-- launching Item Masterpicker--%>
<wctags:itemMasterPicker id="itemMasterPicker"
label="MyItemMasterPicker"/>
</tr>
<tr>
<%-- launching Item Masterpicker--%>
<wctags:genericPicker id="viewPicker" objectType="wt.vc.views.
View" label="
View Picker
using generic" pickerType="tree" />
</tr>
<tr>
<%-- launching Recently Visited Context Picker- Single
Select--%>
<wctags:contextPicker id="containerTypeListSingleSelect" label=
"
Recently Visited Context Picker-
Single Select" pickerTitle="ContextPicker" showRecentlyUsed="true"
displayAttribute="containerInfo.name"/>
</tr>
<tr>
<%-- launching Recently Visited Context Picker- Multi
Select--%>
<wctags:contextPicker id="containerTypeListMultiSelect" label=
"Recently
Visited Context Picker- Multi Select" pickerTitle="ContextPicker"
showRecentlyUsed="true" displayAttribute="containerInfo.name"
showMultiSelectRecentlyUsed="true"/>
</tr>
</table>
</body>
</html>
Background
The context picker is used when you have a requirement to perform an operation
that is based on certain context.
Scope/Applicability/Assumptions
It is assumed that your <MyPage>.jsp file in which you are putting tag
includes “/netmarkets/jsp/begin.jspf” or “/netmarkets/jsp/
beginPopuf.jspf” file and “/netmarkets/jsp/end.jspf” files.
Intended Outcome
You should see a text box and a Find icon along with the specified label after
using the tags for context picker. After clicking the Find icon, the context picker
will be launched.
Solution
Use the Context Picker Common Component in your JSP file to include Context
Picker in your application.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving JSP, JavaScript, Custom taglibs
• The management of resource bundle file customizations
• Windchill xconfmanager concepts
Solution Elements
Element Type Description
PickerAttributes.xml XML You should use this file to
customize the search criteria
attributes for an object type
for your picker.
Runtime location:
<Windchill>\codebase\
pickerAttributes.xml
searchClientResource.java Resource bundle file You should use this file to
localize the contents of the
pickers.
contextPicker.tag Custom JSP tag file This file contains the
information about the
supported parameters for
Note
You want to disable the type picker in the Context Picker.
Customization Points
Customization Points are listed in following tables:
updateHiddenField.value=oid;
updateDisplayField.value=displayAttr;
Background
The item picker is used when you have a requirement to select specific business
object(s) depending upon certain criteria and use them in your application.
Scope/Applicability/Assumptions
It is assumed that your <MyPage>.jsp file in which you are putting tag includes
“/netmarkets/jsp/begin.jspf” or “/netmarkets/jsp/
beginPopuf.jspf” file and “/netmarkets/jsp/end.jspf” files.
Intended Outcome
You should see a text box and Find button along with the specified label after
using the tags for item picker. After clicking the Find button, the item picker will
be launched.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving JSP, JavaScript, Custom taglibs
• The management of resource bundle file customizations
• Windchill xconfmanager concepts
Solution Elements
Element Type Description
pickerAttributes.xml XML file You should use this file to customize
the search criteria attributes for an
object type for your picker.
Runtime location:
<Windchill>\codebase\picker
Attributes.xml
searchClient Resource bundle You should use this file to localize
Resource.java file the contents of the pickers.
itemPicker.tag Custom JSP tag This file contains information about
file the supported parameters for this tag.
Runtime location:
<Windchill>\codebase\WEB-INF\
tags\itemPicker.tag
SearchableTypes. xconf Properties You should specify component Id
properties.xconf file and corresponding object types in
this file and then run xconfmanager.
Runtime location:
<Windchill>\codebase\com\ptc\
windchill\enterprise\search\server\
SearchableTypes.properties.xconf
custom.js JavaScript file You should specify custom
pickerCallback function for picker in
this file.
Runtime location:
<Windchill>\codebase\netmarkets\
jsp\search\custom.js
</tr>
Customization Points
Parameter Default Possible Req? Description
Value Values
Id Anything Yes An ID is associated
that’s unique with every picker in
in a page the calling
application. This ID
has to be unique for
all pickers, whether of
different types or
same type, in one
page. The id should
not contain "." (dot) in
the name.
componentId pickerSearch Any valid No componentId
component id determines the
specified in attributes that should
picker appear in search
Attributes.xml criteria panel of the
given picker.
pickerCallback Generated at Name of the No Name of the
runtime if user callback customized callback
has not function function that a user
specified this would have to
parameter implement. It’s
recommended that
you specify
pickerCallback
{
var updateHiddenField = document.getElementById(pickerID);
var updateDisplayField = document.getElementById(pickerID +
"$label$");
var myJSONObjects = objects.pickedObject;
for(var i=0; i< myJSONObjects.length;i++) {
var oid = myJSONObjects[i].oid;
// Here “name” is the displayAttribute requested
var displayAttr = eval("myJSONObjects[i].name");
updateHiddenField.value=oid;
updateDisplayField.value=displayAttr;
}
}
Background
The organization picker is used when you have a requirement to select specific
organization(s) depending upon certain criteria and use them in your application.
Typical use case could be that you may want to find parts that are available in
particular organization. In this case, you can have a organization picker and then
through this you can select the organization and pass it on to the search criteria to
perform search for parts.
Scope/Applicability/Assumptions
It is assumed that your <MyPage>.jsp file in which you are putting tag
includes “/netmarkets/jsp/begin.jspf” or “/netmarkets/jsp/
beginPopuf.jspf” file and “/netmarkets/jsp/end.jspf” files.
Intended Outcome
You should see a text box and a Find button along with the specified label after
using the tags for organization picker. After clicking the Find… button, the
organization picker will be launched.
Solution
Use the Organization Picker Common Component in your JSP file to include
Organization Picker in your application.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving JSP, JavaScript, Custom taglibs
• The management of resource bundle file customizations
• Windchill xconfmanager concepts
Customization Points
Parameter Default Possible Req? Description
Value Values
Id Anything that False An ID is associated
is unique in a with every picker in
page the calling
application. This ID
has to be unique for
all pickers, whether
of different types or
same type, in one
page. The id should
not contain "." (dot)
in the name.
componen pickerSearch Any valid No componentId
tId component id determines the
specified in attributes that
pickerAttri- should appear in
butes.xml search criteria panel
of the given picker.
pickerCallback Generated at Name of the No Name of the
the runtime if callback customized callback
user has not function function that a user
specified this would have to
parameter implement. It’s
recommended that
you should specify
pickerCallback
function in custom.
Background
Type Picker Common Component is to be used either for display or for
assignment of type-able items. For example in a search application to select the
type of objects that you are interested to do a search on or in a create application
to create an item of a specific type. It can be used to display the type in case of
edit or view applications. The component can be used in the context/mode of
CREATE, EDIT, SEARCH or VIEW.
Scope/Applicability/Assumptions
• If the Type Picker behavior is to be driven by site/organization preferences viz.
display (list or tree), default type, filter criteria etc, its assumed that you will
extract the relevant information and pass them to the component.
• The component will apply access control policies except for SEARCH mode.
• It is assumed that your <MyPage>.jsp file in which you are implementing
this common component includes “/netmarkets/jsp/begin.jspf” or
“/netmarkets/jsp/beginPopuf.jspf” file and “/netmarkets/
jsp/end.jspf” files.
Intended Outcome
Depending upon the format, you will get either a dropdown or table or a tree:
• Type Picker in DropDown Format
Prerequisite knowledge
To understand this documentation, you need to have an understanding of the
following:
• Basic development involving JSP, JavaScript and Custom taglibs
• The management of resource bundle files customizations
• Windchill xconfmanager concepts
• Windchill Type Identifiers
Solution Elements
Element Type Description
picker.tld tld Tag Library Descriptor (TLD) file,
which contains Type Picker Tag
definition
Run time Location:
<Windchill>\codebase\
WEB-INF\tlds\
typePickerResource.java Java You should use this file to localize
the contents of the Type Picker pop
up.
<your_page>.jsp jsp Your TypePicker Common
Component implementation
containing jsp file.
wt.properties properties You can define
‘wt.typepickerexclude’
property here
Run time Location:
<Windchill>\codebase\
wt.properties
value="myfolder/myDataFetcher.jsp" />
</picker:typePicker>
Points to be taken care while authoring your pickedDataFetcher
• The response of the pickedDataFetcher should contain <DIV> tag with id
same as the Type-Picker id. The content inside the <DIV> tag is extracted and
evaluated to create JSON objects. An example of a typical response will be
<DIV id=”Type_Picker_Id” >
{"pickedObjects":
[
{"type" : "Part" , "theType" : "wt.part.WTPart "},
{"type" : "Document" , "theType" : "wt.doc.
WTDocument”}
]
}
</DIV>
• If you want to access the selected value in the Command, you can get a hold
of it through the NmCommandBean
HashMap comboBox_hmap = commandBean.getChangedComboBox();
Object comboBox = comboBox_hmap.get(GUIComponent_Id);
Background
The user picker is used when you have a requirement to select specific user(s)
depending upon certain criteria and use them in your application. Typical use case
could be that you may want to find parts which are created by certain user. In this
case you can have a user picker and then through this you can select the user and
pass it on to the search criteria to perform search for parts.
Scope/Applicability/Assumptions
It is assumed that your <MyPage>.jsp file in which you are putting tag
includes “/netmarkets/jsp/begin.jspf” or “/netmarkets/jsp/
beginPopuf.jspf” file and “/netmarkets/jsp/end.jspf” files.
Intended Outcome
You should see a text box and Find icon along with the specified label after using
the tag for user picker. After clicking the Find icon, a user picker will be launched.
Solution
Use the User Picker Common Component in your JSP file to include User Picker
in your application.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving JSP, JavaScript, Custom taglibs
• The management of resource file customizations.
• Windchill xconfmanager concepts
Solution Elements
Element Type Description
PickerAttributes.xml XML pickerAttributes.xml XML file You
should use this file to customize the
search criteria attributes for an object
type for your picker.
Runtime location:
<Windchill>\codebase\
pickerAttributes.xml
searchClientResource Resource bundle You should use this file to localize the
Customization Points
Customization Points are listed in following tables:
Background
The current way of picking of participants is limited to Users, Groups, and is not
consistent across Windchill. The new Participant Picker Common Component
gives consistent behavior across Windchill. Participant Picker gives you the ability
to search Participants of type User, Group, and Organization. It provides a wide
variety of search scope criteria using which you can narrow down the search.
Note
This topic describes how to customize a JCA-based participant picker for use
in JCA tables. In Windchill 11.0, a new participant picker based on AngularJS
has been introduced and PTC recommends using it for standalone, single-page
applications based on AngularJS, HTML, or Javascript. For more information,
see Configuring a Participant Picker in AngularJS on page 1036.
Scope/Applicability/Assumptions
• Using in Windchill Client Architecture table: You should define a Windchill
Client Architecture action, and point the action to a JSP page that has
participant picker tag. Provide the required attributes “action Class” and
“action Method “to the participant picker tag. Add the Windchill Client
Architecture action you created to the desired Windchill Client Architecture
table. When you click the action, it will launch the Participant Picker Wizard.
Select desired participant and click OK. The Picker will invoke the action
Method of the action Class that you have provided. In that method, you will
consume or process the selected participant in a desired way.
• Using Participant Picker in combination with Property Picker: The assumption
is that you know how to use the Property Picker. The action attribute of your
Property Picker should point to the JSP page that has participant picker tag.
The required attribute “action Class” should “”(empty) and “action Method “
should be “JavaScript:${pickerCallback}()”. ${pickerCallback} is the
pickerCallback JavaScript function that you supplied to Property Picker. After
you select the desired participants and click OK in the wizard, your
pickerCallback JavaScript function will be invoked with JSON object
containing the picked participants.
Solution
Use the Participant Picker to search for participants, and add the selected
participants to a Windchill Client Architecture table or text box in a Property
Picker.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• How to add Windchill Client Architecture actions to a Windchill Client
Architecture table, how to dynamically update the table with selected
participants.
• How to configure a Property Picker, how to author JavaScript picker Callback
functions.
Solution Elements
Element Type Description
actionClass Tag Attribute Name of the action class that
needs to be invoked for processing
the selected Participants.
actionMethod Tag Attribute Name of the action method that
needs to be invoked for processing
the selected Participants.
select Tag Attribute This will determine whether the
picker allows multiple selections
("multi"), or just a single select
("single").
participantType Tag Attribute Use this to set the default to any
Participant type. The class com.
ptc.core.components.beans.
PrincipalBean has four string
constants defined, which one can
be pass to this attribute. The
constants are ALL_
PARTICIPANT, USER, GROUP
and ORG.
singleParticipantType Tag Attribute Use this to set the default
Participant type specified in the
tag attribute participantType as the
Sample Code
<jca:participantPicker
actionClass="com.ptc.netmarkets.principal.CustomPrincipalCommands"
return result;
}
}
You should write a static method as actionMethod. It will take only one argument
i.e., NmCommandBean. The selected participants are sent to this method as text
parameters. With in the component these values are stored in hidden variable. The
name of the hidden variable is defined as a static String in “com.ptc.windchill.
enterprise.picker.principal.PrincipalBean”. To extract selected participants use
PrincipalBean.PARAM_SELECTED_PRINCIPALS. This will return “#”
separated DN (Distinguished Name).
Adding Association
To add association in the Participant picker, you need to provide three attributes as
highlighted in the following sample. The attribute associationMap takes
LinkedHashMap. You supply the key, value pairs to this map. Key’s are the java
String literals. When user selects an association, this key String literal is passed
back to the actionMethod as text Parameter. Values are localized string displayed
in the dropdown list. Component uses LinkedHashMap to retain the order in
which the key value pairs are added while displaying in the dropdown list.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/components"
prefix="jca"%>
<%@ page import="java.util.LinkedHashMap"%>
<%@ page import = "com.ptc.windchill.enterprise.picker.principal.
PrincipalBean" %>
<%
LinkedHashMap associationMap = new LinkedHashMap();
associationMap.put("GUEST", "Guest");
associationMap.put("MEMBERS", "Members");
The above code will render association dropdown as shown in the following
figure.
In the above example, you are trying to add a role to the participant. You move the
desired participants to Participants List, select a role from the association list and
click OK. The actionMethod code will now look like this.
public class CustomPrincipalCommands {
public static FormResult addPrincipal(NmCommandBean cb) throws
WTException {
FormResult result = new FormResult(FormProcessingStatus.SUCCESS);
result.setNextAction(FormResultAction.REFRESH_OPENER);
String principals = cb.getTextParameter(PrincipalBean.PARAM_
SELECTED
_PRINCIPALS);
if (principals == null) {
result.setStatus(FormProcessingStatus.FAILURE);
return result;
}
ArrayList<String> selectedPrincipals = new ArrayList<String>();
int start = 0;
int pos = principals.indexOf("#", start);
while (pos != -1) {
String principal = principals.substring(start, pos);
selectedPrincipals.add(principal);
start = pos + 1;
You can extract the selected association from text parameter as highlighted in the
above code.
The above code will render the email subscription field as shown in the following
figure.
Sample JSP to launch the Picker and send back the picker values to a
Textbox.
You can use Property Picker tag to render a Textbox and Find button to launch
Participant Picker. The Find button has to declared in actions.xml as described in
the above sections. The Property Picker by default provides a JavaScript call back
Coming back to the Participant Picker, one can get the callback JavaScript
function name as request parameter, when Participant Picker is launched from
Property Picker.
<c:set var="pickerCallback" value=
"<%=request.getParameter("pickerCallback")%>"/>
<jca:participantPicker
actionClass=""
actionMethod="JavaScript:${pickerCallback}()"
participantType="<%= PrincipalBean.GROUP %>"
<jca:participantPicker>
Background
This AngularJS–based participant picker common component provides the ability
to select from an expanded list of participants, including users, groups,
organizations, roles, and actors. It provides a wide variety of search scope criteria
with which you can narrow down the search, including the ability to configure
LDAP as a selectable option.
Note
This topic describes how to customize an AngularJS-based participant picker
for use in a standalone, single-page application based on AngularJS, HTML,
or Javascript. The AngularJS-based participant picker was introduced in
Windchill 11.0. PTC recommends using it for standalone, single-page
applications. To customize a participant picker to use in a JCA page, refer to
the JCA-based participant picker topic Configuring a Participant Picker in
JCA on page 1024.
Scope/Applicability/Assumptions
To use an AngularJS participant picker app in a Windchill Client Architecture
table, you should define a Windchill Client Architecture action, and point the
action to a JSP page that has a participant picker tag. Add the Windchill Client
Architecture action you created to the desired Windchill Client Architecture table.
Intended Outcome
The selected participants are populated in an element such as a table, text field, or
list.
Solution
Use the Participant Picker to search for participants and populate the results into a
table, text field, or list or other element that you choose.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• How to add Windchill Client Architecture actions.
• How to author JavaScript picker Callback functions.
• How to configure a standalone application page in AngularJS 1.2. Refer to the
AngularJS Developer Guide for additional information.
Solution Elements
Element Type Description
auto-suggest Boolean Set this to “true” to have the
picker work as an auto-suggest
search.
auto-suggest- Integer The limit of results to return to
display-limit auto-suggest. This value will
override the typical value returned
from the server but only if it is
less than the max count set on the
property
com.ptc.netmarkets.user
Search.maxCount.
auto-suggest- String The text to display in the auto-
placeholder suggest input field. By default the
value is Enter participant
name.
auto-suggest- String Specifies which attribute to search
user-search- on for user type in auto-suggest. It
field only works when user is the only
defined participant type available
in the picker. The options are
]}"
default-columns-display="{'users':[
{'name':'Organization', 'hidden': true},
{'name':'status', 'hidden': false}
]}"/>
</form>
Sample Code
1043
Configurable Link Tables
Special link types, known as configurable links, are provided which can be used to
configure and display additional relationship tables on document and part
information pages. JSP files have been provided to allow sites to implement and
display these configurable link tables. The tables then display in the navigation
link menus on the information page.
For more information, see the section Type and Attribute Management in the
Windchill Help Center.
Note
The load file loads both the link types and the association constraints.
• <Windchill>/codebase/config/actions/
ConfigurableLinkExamples-actionmodels.xml
• <Windchill>/codebase/config/actions/
ConfigurableLinkExamples-actions.xml
• <Windchill>/codebase/com/ptc/windchill/enterprise/
object/configurableLinkExamplesResource.class
The file ties the registry of the Customize menu on information pages to the link
type that is implemented for the table, the table header, and the action title.
• <Windchill>/codebase/com/ptc/windchill/enterprise/
ConfigurableLinkExamples.xconf
• <Windchill>/codebase/com/ptc/windchill/enterprise/
ConfigurableLinkExamples-wt.properties.xconf
• <Windchill>/codebase/com/ptc/windchill/enterprise/
ConfigurableLinkExamples-service.properties.xconf
Note
The actionmodels.xml file overrides the Customize menu on information
pages with the Configurable Link Examples menu on the end. If you have
customized your third-level navigation menus, then these lists must match or
your customizations will be overridden. As an alternative, you could add the
Configurable Link third-level navigation to the actions entry for your info
pages.
Note
For steps 5 through 8, the OOTB example code is located in files with the
prefix �ConfigurableLinkExamples�, however you should make
any customization changes by creating files with the
�ConfigurableLinkCustomizations� file prefix.
• ConfigurableLinkCustomizations.xconf
• ConfigurableLinkCustomizations-wt.properties.xconf
• ConfigurableLinkCustomizations-service.properties.xconf
<csvtypeId>wt.configurablelink.ConfigurableMastersLink</csvtype
Id>
<csvpermission>+</csvpermission>
<csvprincipal>ALL</csvprincipal>
<csvpermissionList>0/1/2/5</csvpermissionList>
<csvstate/>
</csvAccessRule>
3. Update the product and/or library container templates to include the access
control policy rules for the ConfigurableMastersLink and/or its subtypes. Any
new products or libraries created with the updated templates will automatically
load the access control policy rules. Following is an example of an access
control policy rule that can be added to a product or library templates that will
<externalTypeId>wt.configurablelink.ConfigurableMastersLink</ex
ternalTypeId>
<lifecycleState>ALL</lifecycleState>
<WTPrincipalReference isInternal="true">
<groupName>teamMembers</groupName>
<groupType>teamMembers</groupType>
</WTPrincipalReference>
<grantPermissionSet>
<AccessPermissionSet>
<permissionField name="READ"/>
<permissionField name="MODIFY"/>
<permissionField name="CREATE"/>
<permissionField name="DELETE"/>
</AccessPermissionSet>
</grantPermissionSet>
</AccessControlRule>
Example
<actionmodels>
<model name="configLinks"
resourceBundle=
"com.ptc.windchill.enterprise.object.configurableLinkExamplesResource">
Note
• To make the Configurable Links available in Part Structure Browser or on
the Information pages of part, documents, or changes, you must first add
the properties to the site.xconf file.
• Using the property will control the display the Configurable Links tab for
all the users.
• To enable the property-based display control for existing custom
configurable links tables, you must add appropriate filters to the
corresponding action.
Note
Using the standard profile will control the display the Configurable Links tab
for specific users.
There are following UICOMPONENTs that can be used for Configurable Link
display control:
• VIEW_PSB_DESCRIBE_CONF_LINKS_TABLE for Describe Link
• VIEW_PSB_REFERENCE_CONF_LINKS_TABLE for Reference Link
• VIEW_PSB_REVISION_CONF_LINKS_TABLE for Revision Link
• VIEW_PSB_MASTER_CONF_LINKS_TABLE for Master Link
Example
Examples of actions with UICOMPONENT and filters:
<action name="childObjectsTable_customDescribeLink" uicomponent="VIEW_
PSB_DESCRIBE_CONF_LINKS_TABLE">
<command url="/netmarkets/jsp/object/configurableLinkRoleATable.jsp" />
<includeFilter name="hideForChangeTemplates"/>
<includeFilter name="hideBasedOnChildDescribeProperty"/>
<nonSupportedTypes value=="wt.vc.Mastered"/> <!-- This kind of link is
not applicable for Mastered Context Objects -->
Note
Iteration Resource is not supported for configurable link collection.
Note
The Collect Configurable Links toolbar is visible only when the value of the
property
com.ptc.core.collection.show.configurable.links.ui in
wt.properties is set to true.
The sample user interface for the collection of configurable link contains the
following:
Icon Description
Collect related describe child objects
Collect related master child objects
Collect related reference child objects
Collect related revision child objects
Collect related describe parent objects
Collect related master parent objects
Collect related reference parent objects
Collect related revision parent objects
Note
If you want to use an existing collection definition and collection tool, skip the
following steps and see Step 4 - Add configurable link collection definition to
Windchill UI on page 1064.
Tip
To avoid data corruption, create a backup of the
SampleConfigurableLinksCollectionDefinitions.xml
file before editing it.
Note
Each attribute defined in the Declare must be linked in Retrieve within
CollectionDefinition.
Note
If this file is not available, create it. For more information, see Sample
Configurable Links Collection Definitions File on page 1065.
6. Notice that the CollectionTool section has multiple tags for collection.
Create a copy of one of the Collection tags and edit the values for
collectionServiceKey and collectedAsKey.
An example is as follows:
Note
The values specified for collectionServiceKey and
collectedAsKey must match the values of the
CollectionDefinition name and type in the
SampleConfigurableLinksCollectionDefinitions.xml
file.
Note
To verify your custom tool without pushing your changes to Windchill,
specify the value of parentCollectionComponentID as
ConfigLinksCollectionCompExample. On a successful
verification, replace the value of
parentCollectionComponentID with the value of the user
interface that you wish to add the collection tool on.
</CollectionToolsDefinition>
<CollectionInstances>
<!-- Configure custom collection component instances here.
-->
<!-- This collection component instances configuration is
different than that of configured in OOTB -->
<!-- In CollectionComponentInstance collectionComponentID and
preferencesRoot is restricted. -->
<!-- Instead inn CollectionComponentInstance
parentCollectionComponentID is mandatory in which this custom
configuration to be pushed. -->
<!-- parentCollectionComponentID is ID of the OOTB Collection
Component in which these additional tools to be pushed. -->
<!-- How to find the correct collectionComponentID please refer
the help document -->
-->
<CollectionComponentInstance parentCollectionComponentID=
"SaveAsInCommonspace">
<description>
This collection additional component instance is
used by the Save As in Commonspace command
</description>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionComponentInstance parentCollectionComponentID=
"SaveAsInWorkspace">
<description>
This collection additional component instance is
used by the Workspace Save As command
</description>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REFERENCE_LINK_CHILDREN"
defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REFERENCE_
LINK_PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_MASTERS_LINK_CHILDREN"
defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_MASTERS_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
</CollectionComponentInstance>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REFERENCE_LINK_CHILDREN"
defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REFERENCE_
LINK_PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_MASTERS_LINK_CHILDREN"
defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_MASTERS_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
</CollectionComponentInstance>
<CollectionComponentInstance parentCollectionComponentID=
"CollectItemsFromChangeItem_AffectedItems">
<description>
This collection additional component instance is
used by the affected objects UI command
</description>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REFERENCE_LINK_CHILDREN"
defaultCollectionToolOptionId="None"/>
<CollectionComponentInstance parentCollectionComponentID=
"CollectItemsFromChange_ResultingItems">
<description>
This collection additional component instance is
used by the Resulting objects UI command
</description>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_DESCRIBE_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
CHILDREN" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REVISION_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REFERENCE_LINK_CHILDREN"
defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_REFERENCE_
LINK_PARENTS" defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_MASTERS_LINK_CHILDREN"
defaultCollectionToolOptionId="None"/>
<CollectionToolUsage id="COLLECT_CONFIG_MASTERS_LINK_
PARENTS" defaultCollectionToolOptionId="None"/>
</CollectionComponentInstance>
</CollectionInstances>
</CollectionComponentConfig>
Events
Events that are configured to set\reset the values of IBA attributes and the
respective tags that hold values are:
Event Tag
Creation of Configurable Revision onCreation
Link. The value is only set if value is
not already set.
Copy forwarded Configurable Revision onReviseOfRoleA
Links on the revise of Role A.
Copy forwarded Configurable Revision onReviseOfRoleB
Links on the revise of Role B. This
option is only available if the
preference is set to True.
Note
• If there are multiple parts to an attribute (for example Real Number with
precision), the parts must be delimited by '|'.
• The delegate only supports setting the attribute if the attribute has a single
value. In the case of a multi-valued attribute that has more than one value,
the delegate will not set any value for the attribute.
• Attributes values can be defined for the Parent type and are applied to soft
types by inheritance.
1073
Customizing Indexing Behavior
You can modify search engine index information that is associated with a
Windchill business object.
Configure DefaultIndexObjectBuilder
Provide the implementation for the following method with a signature:
protected void setAdditionalAttributes(EPMDocument
indexable, TypeInstance ti, WCIndexingObject
indexingObject, WTCollection sharedMapCollection) throws
WTException
To use a customized DefaultIndexObjectBuilder class, you must update
the service.properties file to reflect this change.
The following is the default entry:
# #####################################################
# The wt.index.builder.IndexObjectBuilder service.
# ###########################################################
wt.services/svc/default/wt.index.builder.IndexObjectBuilder/
null/wt.index.Indexable/0=wt.index.builder.
DefaultIndexObjectBuilder
/duplicate
For this example, assume that you have a custom
DefaultIndexObjectBuilder named DemoIndexObjectBuilder that
you want to use to index. If you want to override the default
DefaultIndexObjectBuilder, you must add the following line to
service.properties : wt.services/svc/default/
wt.index.builder.IndexObjectBuilder/null/
wt.epm.EPMDocument/0=
wt.index.builder.DemoIndexObjectBuilder/duplicate
Note
This value should be entered on one line.
setAdditionalAttributes
You can override the custom_
setAdditionalAttributes(EPMDocument indexable,
TypeInstance ti, WCIndexingObject indexingObject,
WTCollection sharedMapCollection) method and add your specific
code into this method.
/**
* Demo IndexObjectBuilder implementation for EPMDocument object
type.
*/
@Override
protected void setAdditionalAttributes(EPMDocument indexable,
TypeInstance ti,
WCIndexingObject indexingObject, WTCollection sharedMapCollection)
throws WTException {
//call the setAdditionalAttributes method of super class to
keep the
//existing implementation intact
//Get the custom for which user wants solr field. Like SOME_
ATTRIBUTE
IndexAttributeInfo attributeInfo = getAttributeInfo
("SOME_ATTRIBUTE", demoVal, false);
indexingObject.addToUnmappedAttInfo(attributeInfo);
Customizing Solr
Solr has the following configuration files:
• <$solr-home>\wblib\conf\schema.xml
• <$solr-home>\wblib\conf\solrconfig.xml
The value for <$solr-home> is the Solr home directory you specified when
installing Solr with Windchill.
Note
The default core is wblib. If you plan to use multicore, then this folder would
be replaced by the core names.
Language Customization
To support any new language, customize indexing, or customize searching
behavior for specific fields, then you must modify schema.xml.
The fields for all the languages supported in Windchill are configured out-of-the-
box.
Index search queries are targeted against the Keyword field, which has the type
text_rlp. For every language, Windchill defines different fields (text_ja for
Japanese, text_kor for Korean, and so on).
When adding a new language, you must introduce a new field with a name of your
choice. For example, the following is the entry for text_rlp:
<fieldtype name="text_rlp" class="solr.TextField" positionIncrementGap=
"100">
<analyzer type="index">
<tokenizer class="com.ptc.search.solr.tokenization.PTCTokenizerFactory"
defaultLanguage="jpn" defaultFieldType="text"
fieldTypesPerLangauge="jpn-text_ja,eng-text,deu-text_deu,
kor-text_kor,fra-text_fr,ita-text_ita,zhs-text_zhs,ell-text_ell,ru-text_
rus" />
</analyzer>
<analyzer type="query">
<tokenizer class=
"com.ptc.search.solr.tokenization.PTCQueryTokenizerFactory"
defaultFieldType="text"
fieldTypesPerLangauge="jpn-text_ja,eng-text,deu-text_deu,
kor-text_kor,fra-text_fr,ita-text_ita,zhs-text_zhs,ell-text_ell,ru-text_
rus" />
</analyzer>
</fieldtype>
For example, for Japanese, ISO 639 code is jpn and the field name is text_
ja. Therefore the value is jpn-text_ja.
Note
For more detailed information about analyzers, filters and tokenizers, see the
following link:
http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters
Note
This step is not performed in a
separate filter because of possible
subword combinations.
This filter is a replica of solr.WordDelimiterFilter, which is shipped
with Solr. It has been customized to protect the following characters: ".", "-" and
"_"
Splitting is affected by the following parameters:
• generateWordParts=1
Parts of words are generated: "whistle-blower" = "whistle" "blower"
Note
Ensure that the same order of tokenizers is maintained at indexing and query
time. Tokens generated at query time should be the same as when indexing for
a given word.
Synonyms
The synonym entries in $solr-home\wblib\conf\synonyms.txt ensure
that searching on one word can find records with synonymous words. You can edit
this file to enter or remove synonyms.
The SynonymFilterFactory filter is configured for English text fields.
autoCommit
Windchill uses the Solr auto commit feature to commit the index information
automatically after certain criteria is met.
You can configure autoCommit in solrconfig.xml.
This criteria is specified under the following element:
<updateHandler class="solr.DirectUpdateHandler2">
<autoCommit>
<maxDocs>1000</maxDocs>
<maxTime>60000</maxTime>
</autoCommit>
maxDocs
maxDocs is the maximum uncommited Windchill business object documents
before autocommit triggered
maxTime
maxTime is the maximum time (in milliseconds) after adding a Windchill
business object document before an autocommit event is triggered
Indexed searches perform better when the maxTime and maxDocs values are
higher.
However, an object does not appear in search results unless the index information
is committed.
Note
Use higher values when you run bulk indexing.
Customization Points
Update the service entry with Custom class in "service.properties" as
shown in the sample code. In the example, facetCustomClass is the name of
custom class.
wt.services/svc/default/
com.ptc.windchill.enterprise.search.facet.FacetService/
null/null/0=
com.ptc.windchill.enterprise.search.facet.FacetCustom
Class/duplicate
Implement the inherited
method FacetService.isAttributeVisible(AttributeTypeIden
tifier). The isAttributeVisible API returns boolean value which is set
to true by default. You can customize theisAttributeVisible API to
return false in case the customer wants to hide any IBAs from facet.
Example:
public booleanisAttributeVisible(AttributeTypeIdentifier ibaAttribute){
if(ibaAttribute.getAttributeName().equals("name of attribute")){
return false;
}
return true;
}
Note
The WTPart object is not a default content holder. To enable support for
attachment on parts, the Attachment on Parts preference must be set to Yes.
This preference is available under Part Management in the Preference
Management.
After performing the above steps, Text Preview column will be added as part of
custom table view.
4. Set the value of the property wt.index.enableTextPreview to true to
enable the Text preview column.
5. Re-index the existing data.
This chapter explains how to encrypt passwords currently stored as plain text in a
file.
Scope/Applicability/Assumptions
• Assume you have code that adds a new .xconf property for Windchill use
whose value contains sensitive information.
• Assume you have code that adds a property which isn’t managed by the
Windchill xconf framework whose value contains sensitive information.
• Assume you have code that reads Windchill .properties files directly to access
property values.
Intended Outcome
Once a property is encrypted the corresponding value for that property will no
longer appear in plain text and instead, appear in an encrypted form.
For example, one of the out of the box property values that Windchill can
optionally encrypt is the wt.pom.dbPassword .xconf property.
Prior to encryption, in <Windchill>/site.xconf this value appears as:
<Property name="wt.pom.dbPassword" overridable="true" targetFile=
"db/
db.properties"
value="my_password"/>
Solution
Use Windchill’s encryption mechanism to provide a secure means to store
sensitive property value information.
To ensure a standard practice, properties which require encryption should ideally
be xconf managed, using xconfmanager set commands, if able. This ensures an
easier process to encrypt the property. However, there may be design
considerations or architecture issues which prevent the property from being xconf
managed, such as the file not strictly containing key/value pairs or the xconf
framework not being present in the classpath that can influence whether that is
feasible.
Prerequisite knowledge
To apply this best practice, you need to have an understanding of the following:
• Basic development using Java
• Optionally Windchill xconf framework
Solution
To ensure a standard practice, properties which require encryption should ideally
be xconf managed, using xconfmanager set commands, if able. This ensures an
easier process to encrypt the property. However, there may be design
considerations or architecture issues which prevent the property from being xconf
managed, such as the file not strictly containing key/value pairs or the xconf
framework not being present in the classpath that can influence whether that is
feasible.
Use Windchill’s encryption mechanism to provide a secure means to store
sensitive property value information.
Prerequisite Knowledge
To apply this documentation, you need to have an understanding of the following:
• Basic development using Java
Solution Elements
Element Type Description
WTKeyStore Java Class An interface and API to
the secure location for
encrypted values. This
class can be used to
encrypt and decrypt the
values. See the Javadoc
for the API’s.
This class contains the
primary API to encrypt a
property value and a
secondary means to
decrypt a value.
WTKeyStoreUtil Java Class An interface and API that
provides helper methods
to obtain the
validProperties.list
properties and decrypted
values. See the Javadoc
for the API’s.
This class contains the
primary API used to
determine if a property
value is encrypted and
decrypt it accordingly.
validProperties.list List File The <Windchill>/bin/
adminTools/sip/
validProperties.list file is
a list of Windchill xconf
managed properties
which can be encrypted.
Each property is
contained on a separate
line as is the fully name
of the .xconf managed
property.
This file is how
Windchill’s xconf
framework determines
what properties should be
Where property_name is the property name for which you want to decrypt a
value for, property_value is the value that may currently be encrypted
and product_root is the fully qualified path to <Windchill> (or
<adapater_home> for adapter installations).
A code example for the usage of this API is as follows:
final String encrypted_value = “encrypted.wt.pom.dbPassword”;
final String property = “wt.pom.dbPassword”;
final String PATH = “D:\ptc\Windchill\”;
String decrypted = com.ptc.windchill.keystore.WTKeyStoreUtil.
decryptProperty(property,encrypted_value, PATH);
The string decrypted now contains the decrypted value and can be used
properly elsewhere in the code where it is relied on.
The string decrypted now contains the decrypted value and can be used
properly elsewhere in the code where it is relied on.
Where property_name is the property name for which you want to decrypt a value
for, property_value is the value that may currently be encrypted and product_root
is the fully qualified path to <Windchill> (or <adapater_home> for adapter
installations).
Note
Any code that relies on this value must be updated to properly decrypt it.
The string decrypted now contains the decrypted value and can be used properly
elsewhere in the code where it is relied on.
Customization Points
For each solution element whose usage involves the use of parameters, provide a
2nd-level section with a table that describes all of the available parameters. This
can be used for API methods, XML elements, JSP tags, etc. Use the following
template for the table(s):
Limitations
The properties that are encrypted need to be accessible from the server side as the
encryption mechanism relies on a location that is not web accessible from a client
for security purposes. There is minimal performance overhead for encrypting and
decrypting a property. However, it should be noted that the underlying
implementation of the Java keystore relies on a singleton pattern and access to the
keystore is synchronized.
}catch(IOException e){
logger.error("Could not load keystore", e);
}
Decrypting a property:
String product_root = WTProperties.getLocalProperties().
getProperty(“wt.home”);
String value = “encrypted.wt.pom.dbPassword”;
String property = “wt.pom.dbPassword”;
// decrypt encrypted values
value = WTKeyStoreUtil.decryptProperty(property, value, product_root);
/* value can now be used as normal as it will contain the decrypted value
*/
if(isCompletePropertiesListFile(product_root)) {
/*
* add a hardcoded list of dynamic properties that will
* utilize regular expressions to determine what to encrypt
* for dynamic property names.
*/
propertiesList.add(WT_FEDERATION_DEFAULTAUTHORIZATION);
propertiesList.add(NEW_REGULAR_EXPRESSION); // NEW
For better URL handling, it is recommended that you include the following code
to the login page so that newer browsers will not drop the hash token that specifies
the state of the application.
<script type="text/javascript">
if (window.location.hash) { //Handle logging in to a bookmark
document.forms[0].action += window.location.hash;
}
</script>
To customize the appearance and behavior of the login window, the window
object can be pre-populated during page load with a custom SmartClient window
instance. You can use the example from the SmartClient documentation or modify
the one provided by PTC out-of-the-box:
isc.RPCManager.loginWindow = isc.Dialog.create({
src: 'app/login/loginSuccess.jsp?ptscsc=true',
showModalMask: true,
isModal: true,
title: "",
autoCenter: true,
showCloseButton: false,
showMinimizeButton: false,
width: 400,
height: 350
});
Note
For a general overview of comparing structures, see the “Comparing
Structures” online help topic in the Windchill Help Center.
Example
This is an example for how to convert a custom matcher.
public class CustomDSBGraphProcessorDelegate extends
DSBAbstractMatcher {
@Override
public int matchEdges(DSBEdge sourceEdge, DSBEdge targetEdge)
{
// Custom matching logic
}
@Override
public List<Attribute> initRequiredEdgeAttributes() {
// Edge attributes required for matching
}
@Override
public List<Attribute> initRequiredNodeAttributes() {
// Node attributes required for matching
public Collection<CBStructureNode>
getChildrenFromCache(String collectorCacheID,
Collection<String> seeds, HttpServletRequest request) throws
InvalidCollectorCacheException, InvalidCollectorSeedException,
CollectionException;
}
The inputs to the API are:
• Collector Cache ID (String): This is the parameter passed to the custom filter
application in the URL when the custom filter application is launched (CB_
CCID parameter)
• Seeds/Collection of components to traverse (Collection of Strings) : For the
first call, this should contain the id passed to the custom filter application in
the URL when the custom filter application is launched (CB_SEEDID), for
subsequent calls, the collection should contain the ids of the components
returned from previous call that need to be traversed further to get to the CAD
modules – when all CAD modules are retrieved, then this API should not be
called anymore.
• Request : As the customization may execute within the context of a separate
web app, the HTTP request object needs to be passed in as input to the
Context Builder API such that Windchill picks up the authenticated user, the
user locale, HTTP session specific data, etc to establish the appropriate
context for the execution of this API. If the request object is null, then it is
assumed that no initialization of context is required.
The output of this API is:
• A collection of CBStructureNode : This object would contain a child
component id (string), the child Persistable object, a link id (string), the link
Persistable object (between parent and child), the parent id (string), a string
representing the path of that component in the structure and its inclusion status
For each combination of child component id + path we would have a
CBStructureNode object
Exceptions may be thrown in the following situations:
• InvalidCollectorCacheException - collector cache id is no longer
valid
• InvalidCollectorSeedException - seed object(s) passed are invalid
(we cannot refresh them)
1119
Association Constraints
This section explains how to create association constraints within change
management.
Background
Association constraints can now be created for restricting the types of affected and
resulting objects that can be associated to a change object. The association links
for the affected and resulting objects are now typed which will allow for creating
multiple subtypes of the links.
This means that a change object type X can be constrained for using a particular
type of affected data, while a different change object type Y can be constrained
using an entirely different soft-type link of affected data. By default, no
constraints are defined against any of the change objects and their affected or
resulting links. When no constraints are defined, all supported changeable objects
can be associated to affected or resulting object tables.
Association constraints might be used if you have multiple types of change objects
for different purposes. For example a Publications Request is used for processing
a change request for documents. In this case an association constraint could be
created for the change request “Publications Request” and documents, that only
allow users the ability to associate documents and no other objects to the affected
objects of Publications Requests. All supported objects types in the affected
objects table for the base type change request would still be allowed.
Scope/Applicability/Assumptions
• Assumes you have used the type manager and created constraints.
• General Knowledge of the change objects and the role they play in the change
process.
Intended Outcome
The expected results of applying this solution will be that affected and resulting
objects can be constrained to particular types for a specified change object type.
Prerequisite Knowledge
To perform this task, you must have an understanding of the following:
• Using the Type Manager and creating association constraints.
• Basic Knowledge of the change objects and the role they play in the change
process.
The section below includes references to many or all of these subjects.
Solution Elements
Element Type Description
wt.change2.ReportedA Link The link class for associating
gainst class affected objects on a Problem
Report or Variance
wt.change2.RelevantRe Link The link class for associating
questData2 class affected objects on a Change
Request
wt.change2.AffectedAc Link The link class for associating
tivityData class affected objects on a Change Task
wt.change2.ChangeRe Link The link class for associating
cord2 class resulting objects on a Change Task
When defining the association constraint the Change Object type is the driver for
what relationship link is used. The
ChangeService2.storeAssociations will derive the correct link type
given the Change Object and the base link class and update the link to use the
right type for the defined constraint.
Customization Points
The change wizard form delegates and processes will create the links
automatically for the defined constraint link type. Typical use cases to customize
the creation of the links may be due to adding additional attributes on the link or
customized processing of change. When customizing the creation of the affected
or resulting links the following order should be followed:
1. The new link object should be created.
2. Any attributes should be initialized with the default or user entered values
3. The change service store association service should be called.
• For details on the steps for creating new associations see the javadoc for
StandardardChangeService.storeAssociations(ChangeIte
mIfc, WTCollection) and ChangeMgmtConstraintHelper.
• Prior to setting subtype attributes on a subtype link the type definition
reference needs to be set. To set the type definition reference, see the javadoc
for
ChangeMgmtConstraintHelper.getTypeDefinitionReferen
ce(Class, ChangeItemIfc).
Adding Attributes
To add an attribute to a complex schema, use the following procedure:
1. From the Manage Complex Schema page, click Add Attribute.
The Manage Attribute page opens.
2. Specify attribute information using the fields and actions on the Manage
Attribute page. The following table describes the fields and actions available:
Field Description
Attribute Name Enter the name of the attribute
Type Select the attribute type.
Note
To add an attribute to the change management links, do one of the following:
• You can add a soft attribute on the OOTB parent or base type.
• You can create a soft type and add an attribute on this soft type.
• You can have a custom models subtype and add a soft attribute or model
attribute.
Note
Only New and Inherited constraints
can be disabled. Modeled
constraints cannot be disabled.
From the Constraints tab, you can:
• Add new constraints.
• Delete constraints.
• Edit constraints.
• Add conditions on a constraint.
• Enable or disable constraints.
1. On the Affected Objects table, select multiple affected object types for which
you want to a set common change intent.
Note
If there are multiple objects of same or different types in the Affected
Objects table, select objects based on the following specification:
Note
The Mapping Rules table is available at the organization context when the
wt.mappingRules.enableOrganizationRules property is set to
true. By default, this property is set to false.
The rules defined at the organization context take precedence over the site
context rules.
Note
If this rule is not defined, then you cannot create redline for parts and the
change notice workflow will not synchronize the affected objects on the other
open change notices with the latest released revisions.
3. Click Apply.
You can Edit or Delete rules from the mapping rules table. For more
information on these actions, see Mapping Rules Table.
Background
As of the Windchill 10.0 release, Multiple Inventory Dispositions on the
AffectedActivityData Link shall be available OOTB. This document
details steps on how to customize Multiple Inventory dispositions by;
• Adding new inventory disposition types
• Adding new inventory disposition values to be used by inventory disposition
types
• Setting a default disposition value.
Scope/Applicability/Assumptions
The action to set inventory dispositions is exposed on the toolbar or on the actions
menu drop-down of the Affected Objects table in the create/edit Change Task
wizard. It is assumed that you have the ability to navigate to that table.
New inventory disposition values can be added using Enumerated Type
Customization Utility (enumCustomize tool). It is assumed you have the basic
knowledge on how to use the tool, if you are not familiar with the tool see The
Enumerated Type Customization Utility on page 2211 for more information.
• Use the Enumerated Type Customization Utility(enumCustomize tool) to
introduce new inventory disposition values for use in the inventory disposition
types
• Use the Enumerated Type Customization Utility(enumCustomize tool) to
specify a default inventory disposition value
• Use the Type and Attribute Management utility to introduce new types of
inventory dispositions.
Intended Outcome
•
○ You shall be able to introduce new inventory disposition values
○ You shall be able to specify a default inventory disposition value
○ You shall be able to introduce new types of inventory disposition types
Solution
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
Solution Elements
Element Type Description
inventory rbInfo Contains the master list of
DispositionRB inventory disposition
.rbInfo values.
Runtime location:
<Windchill>\src
\wt\change2
change2Client Class Resource bundle for
Resource.java inventory disposition
types
Runtime location:
<Windchill>\
srclib\wnc\Change
Management.jar
AffectedActivity XML Loader for
Data.xml AffectedActivityData
Link. Contains OOTB
dispositions and their
values.
Runtime location:
<Windchill>\
loadFiles\type\
standardX20.dtd DTD DTD for disposition
elements
Runtime location:
<Windchill>\
loadXMLFiles
Coreobjects.dtd DTD The IXB DTD for
disposition elements
Runtime location:
<Windchill>\
codebase\registry
\ixb\dtds
/**
* Returns the configurable table.
*/@Override
public ConfigurableTable buildConfigurableTable(String id)
throws
WTException {
}
}
2. Register your builder.
The builder will be discovered dynamically by the MVC framework. In order
for the framework to find your builder, you will need to register either the base
package location of the builder or the builder class in the xml configuration
file under the mvc package in the src_web variant. Here is an example for
AffectedItemsTableBuilder as registered in
ChangeManagement-configs.xml.
• To register the base builder package. Add this to the xml configuration file:
<mvc:builder-scan base-package="com.ptc.windchill.enterprise.
change2.mvc.builders"/>
• Or register the builder class. Add this to the xml configuration file:
<bean class="
com.ptc.windchill.enterprise.change2.mvc.builders.tables.
AffectedItemsTableBuilder "/>
3. The @ComponentBuilder annotation connects the builder with other
components in the system such as JSP’s. The string you put in the
@ComponentBuilder(“changeTask.affectedItemsTable “)
annotation in the builder must be the same builder ID you include in the JSP.
For example affectedItemsTable.jsp has the following to request the
change task affected item component.
<jsp:include
page="${mvc:getComponentURL('changeTask.affectedItemsTable')}"/
>
4. Extend ChangeTaskAffectedItemsTableViews to add your new
inventory disposition types to the link
public class YourTableViews extends
ChangeTaskAffectedItemsTableViews
{
/**
* Get the disposition columns
*/
@Override
/**
* Get disposition value for a given disposition type.
*/
@Override
public InventoryDisposition getDispositionValue(String
componentId,
BinaryLink link) {
/**
* Set the disposition value for a given disposition type. */
@Override
public boolean setDispositionValue(String componentId, BinaryLink
link,
InventoryDisposition disposition) throws WTException {
/**
* Get the default disposition value for a given disposition type
*/
@Override
public InventoryDisposition getDefaultInventoryDisposition(
ChangeLinkAttributeBean
linkBean, String component_id) {
/**
* Get the disposition value set of a given disposition type
*/
@Override
public ArrayList <InventoryDisposition> getInventoryDispositionSet
(ChangeLinkAttributeBean
}
}
6. Register your new disposition handler in the service properties file
(ChangeManagement-service.properties.xconf). The selector
attribute is your new inventory disposition type and the serviceClass is
your new disposition handler.
<! -- Handler for processing the disposition types -->
<Service context="default" name=
"com.ptc.windchill.enterprise.change2.
handler.DispositionHandler"><Option serviceClass="com.ptc.
windchill.enterprise.
change2.handler.YourNewDispositionHandler"
selector="YourNewDispositionType"
requestor="null"
cardinality="duplicate"/>
</Service>
7. Register your disposition types against DispositionDataUtility. You
may also choose to extend DispositionDataUtility to meet your
business need. The service property file to register the dispositions is
ChangeManagement-
components.dataUtilities.properties.xconf.
For example:
<Option serviceClass="com.ptc.windchill.enterprise.change2.
dataUtilities.DispositionDataUtility"
requestor="java.lang.Object"
selector="YourNewDisposition"
cardinality="duplicate"/>
Overview
In this example, you add two global attributes to the Affected Objects and
Resulting Objects tables.
One the Affected Objects, using a subtype of the
AffectedActivityDatalink class a new attribute called “Regulatory
Affected” (boolean type) is added.
• The values should appear as “Yes/No” and read only in the table.
• You should be able to select one or more changeables and set the value at one
time on the set of selected changeables.
• The value set should be retained if you sort or filter the table. This includes
showing a view that removes the column.
One the Resulting Objects, using a subtype of the ChangeRecord2 link class a
new attribute called “Distribution List” is added (string type) is added.
• The value should appear as editable inline single-row of text within the table
row for parts only.
• The value should be required
Note
For this example, no validation other than the type (and distribution list is
required) is done.
Note
Change link Configuration Management only supports one link type per
RoleA. If multiple are defined, only the most specific is used. The user
cannot choose which link to use. For more information on how to create
association constraints within change management, see Association
Constraints on page 1120.
• Two constraints are created with RoleA being the base class
WTChangeActivity2 and RoleB being either the
CustomAffectedActivityData or CustomChangeRecord2 links.
• Only supported APIs are used in the examples
Customization Procedure
The follow procedure outlines the steps required to perform the customization:
1. Create a table view class extending the existing table view class and add the
new attribute to one or more views. Define the attribute(s) as a special column
to allow it to be used in the View Manager. The column does not need to be
rendered in all (or any views). But to add it to views it needs to be defined as a
special column (since the table is against changeables and knows nothing
about links)
See Custom Table Views (Step 1) on page 1146 for more information.
2. Create an MVC Table Builder extending the one registered for the table.
Annotate the builder with @OverrideComponentBuilder and override
any of the following:
• buildConfigurableTable() to return the custom view class.
• buildComponentData() if there is custom data acquisition logic.
• buildComponentConfig() to define other custom configurations
(models, help files)
See Create MVC Builder Table (Step 2) on page 1149.
3. Define a custom Data Utility to render the attribute in Create, Edit and View
modes. See Create a Data Utility (Step 3) on page 1150 for more information.
4. (Optional) Provide a Javascript or pop-up editors needed to support multi-
object edits. See Add Support for Multi-Edit Actions (Step 4) on page 1151
for more information.
5. Define a custom form delegate to process the attributes (The change task
affected/resulting objects step requires a second form delegate to be created)
See Create a Form Delegate (Step 5) on page 1153 for more information.
6. Define a custom actions.xml referring to the custom form delegate for the
wizard step. See Register Form Delegate with Step (Step 6) on page 1157 for
more information.
For more information on how to add the custom service provider property file,
see Adding a Custom Service Provider Property File.
5. Propagate the created xconf files as shown below:
For example, if you have created CustomTableView.xconf and
CustomTableView-service.properties.xconf files at the
location codebase/ext/custom/, then execute the below command to
propagate the xconf files:
xconfmanager -i codebase/ext/custom/CustomTableView.xconf -p
<Service context="default"
name="com.ptc.core.htmlcomp.tableview.ConfigurableTable">
<Option
serviceClass="tableViews.custom.
DistributingChangeTaskAffectedItemsTableViews"
selector="changeTask_affectedItems_table"
requestor="java.lang.Object"/>
</Service>
</Configuration>
Sample Code
/**
* The distributionList will only be added to the Parts and
All views
immediately after
* the name column.
*/
@SuppressWarnings("unchecked")
@Override
public List getOOTBTableViews(String tableId, Locale locale)
throws WTException
{
List<TableViewDescriptor> result =
super.getOOTBTableViews(tableId, locale);
for(TableViewDescriptor descriptor: result) {
if( descriptor.getName().equals(PARTS_VIEW) ||
descriptor.getName()
.equals(ALL_VIEW)) {
Vector<ableColumnDefinition> columns =
@Override
@SuppressWarnings("unchecked")
public List<?> getSpecialTableColumnsAttrDefinition(Locale
locale) {
List<Attribute.TextAttribute> results =
(List<TextAttribute>)
super.getSpecialTableColumnsAttrDefinition(locale);
results.add(new Attribute.TextAttribute
(DistributingChangeRecordConstants.
DISTRIBUTION_ATTRIBUTE,
"Distribution List" /*Should be localized label*/,
locale));
return results;
}
}
@OverrideComponentBuilder
public class DistributingResultingItemsTableBuilder extends
ResultingItemsTableBuilder {
@Override
public ConfigurableTable buildConfigurableTable(String id)
throws WTException {
return new DistributingResultingItemsTableViews();
}
}
Overview
What is different?
• You are rendering a column in a table of changeables (ie. parts, documents)
which represents a value on the binary link associating the changeable to the
change object.
• The value must be retained between:
○ Paging beyond the page limit
○ Sorting the table
○ Changing table views (which may not even display the column or the
row!)
○ Survive additions and removals to the table.
• The class ChangeLinkAttributeDataUtility has many helper
methods and provides useful customization points to extend to assist with
handling the above cases.
• For performance, using the ChangeLinkAttributeDataUtility will
cache the links for the method request so multiple attributes can be processed
efficiently.
Process
The following are the key points that are required to make a working change link
attribute data utility:
1. Extend the class ChangeLinkAttributeDataUtility.
2. Override the method createGuiComponent(String id,Object
datum,ChangeLinkAttributeBean linkBean); The
ChangeLinkAttributeBean is a specialized bean class to support
managing the links in the request.
Example
The following code provides an example for the operations needed on completing
the editing multiple rows and updating the table.
01 function updateRecords(isChecked, componentId, tableId) {
02 var table = tableUtils.getTable(tableId);
03 var store = table.getStore();
04 store.suspendEvents();
05 var selections = table.getSelectionModel().getSelections
();
06 for(var i=0,l=selections.length; i<l; i++) {
07 var record = selections[i];
08 record.data[componentId] = isChecked;
09 record.commit();
10 var oid = record.get('oid');
11 if(oid) {
12 var item = {
13 id : oid+SEP+componentId,
14 value : isChecked
15 };
16 PTC.change.linkAttributeHelper.update(item,
tableId);
17 }
18 }
19 store.resumeEvents();
20 // re-draw displayed rows where data has changed.
21 table.view.doPartialDataChange();
22 }
23
Key to code sample:
• Line 04 – Suspend Events
• Line 08 – Updates text in table cell
• Line 13 – Generate ID readable by change data utilities and form delegates
• Line 16 – Store the data item in the Table Data Manager store
• Line 19 – Resume Events
• Line 21 – Visually update the table with just what changed
Note
By overwriting the action model in a custom actionModels.xml, it is not
necessary to update the MVC table builder because it is already pointing to
this named action model.
It is recommended that you utilize a single form delegate / table. This keeps a
clean separation of step vs. table functionality. If you have embedded objects,
multiple tables or other scenarios using a step form delegate and delegating this to
the table/component sub form delegates is recommended.
Note
The purpose of this method is to detect attributes that need to be modified on
the links, perform these attribute updates and return a collection of all the links
that were modified. These links are subsequently persisted as a collection.
Caution
It is important to only update attributes if they are detected as modified (or
cleared)
/**
* This method is used to post-process attributes on the change
activity
* and change records.
* Note: In the example below we are not checking whether the change
* record is of the type DistributingChangeRecord. This could be done
* by comparing the Type Definition reference of the change record.
* However since this demo is focused on attribute manipulation using
the
* new code>LWCNormalzedObject we have left it out for brevity.
*/
@SuppressWarnings("unchecked")
@Override
protected WTCollection processLinkAttributes(ChangeItemIfc item,
WTCollection binaryLinks) throws WTException {
WTCollection modifiedLinks = super.processLinkAttributes(item,
binaryLinks);
if (binaryLinks != null && !binaryLinks.isEmpty() && item instanceof
WTChangeActivity2) {
// The link bean has knowledge of how of link attributes and
supports
the JCA interfaces.
ChangeLinkAttributeBean linkBean = ChangeLinkAttributeHelper.
getChangeLinkAttributeBean();
linkBean.setFormData(getObjectBean());
for(Iterator<ChangeRecord2> iter = binaryLinks.persistableIterator
(ChangeRecord2.class, true); iter.hasNext(); ) {
ChangeRecord2 record = iter.next();
// The getTableDataValue() will get the attribute from the FORM
data
supporting any specific change table handlers
String value = ChangeLinkAttributeHelper.getTableDataValue
(DistributingChangeRecordConstants.DISTRIBUTION_ATTRIBUTE,
ChangeManagementClientHelper.getReference
(record.getChangeable2()), linkBean);
// The new LWC API for getting and setting attributes.
PersistableAdapter lwc = new PersistableAdapter(record, null,
null,
new UpdateOperationIdentifier());
lwc.load(DistributingChangeRecordConstants.DISTRIBUTION_
ATTRIBUTE);
Object currentValue = lwc.get(DistributingChangeRecordConstants.
@Override
public ObjectFormProcessorDelegate getResultingDataFormDelegate() {
return new DistributingResultingItemsFormDelegate();
}
}
<objecttypename="changeTask" class="wt.change2.
WTChangeActivity2"
resourceBundle="com.ptc.windchill.enterprise.change2.
changeManagementActionsRB">
<action name="affectedAndResultingItemsStep"
id="affectedAndResultingItems" preloadWizardPage="false" required=
"false">
<description>Affected and resulting objects wizard step</
description>
<command class="com.ptc.windchill.enterprise.custom.
delegates.
CustomAffectedAndResultingItemsFormDelegate“
windowType="wizard_step"/>
</action>
</objecttype>
</listofactions>
Background
As a customizer you may want to add additional operations for use in the mass
change wizard. For example, to create a new operation for a custom association
and/or object type. You also may want to extend existing mass change operations
to insert additional processing validation. For example, to validate that the
revisions are all at a RELEASED state prior to performing the Insert Existing Part
operation.
Scope/Applicability/Assumptions
Performing this task assumes pre-existing knowledge of:
• Java
• Creating JSPs
• actions.xml
• Updating properties
Solution
Register filter delegates for processing new or existing operations. Create new
actions, properties, and JSP for new operations.
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
• Basic development involving Java HTML forms, JSP, and XML.
• The actions framework in the Windchill client architecture
• The management of RBINFO file
• Xconfmanager, wt.poperties and service.properties.
Customization Points
Adding and Extending Operations
The mass change client supports the ability to add new or extend existing
operations to the client. The javadoc in the class MassChangeFilterDelegate has
detailed instructions on how to do this.
While the filter delegate handles the processing of the mass change operation, not
all operations are applicable for the selected object types. (For example a
WTDocument is not valid for mass change operations handling part usage links.)
Note
A future Windchill release will make support of Parts Built from CAD
mandatory, and the above property will be removed.
Related Documentation
See Mass Change Supported Types on page 1166 for information on modifying
the supported object types for a mass change operation.
Scope/Applicability/Assumptions
This documentation assumes that you are familiar with updating property files.
During this process you ill update the mass change operation properties in
wt.properties with the supported or excluded object types.
Prerequisite Knowledge
To perform this operation, you must have an understanding of the following:
• xconfmanager
• wt.properties
• service.properties
Solution
Solution Elements
Element Type Description
wt.properties properties Location for registering
the supported and
excluded types
service.proper properties Location for registering
ties the validation supported
types for operations.
com.ptc.windchill class Validates that the
.enterprise. operation has valid types
massChange. of objects
validators.
MassChange
Operation
Validator
Note
The following example uses the out of the box supported types for the Insert
Existing Part operation (addPartUsage).
Related Documentation
• Mass Change Operations on page 1158
Preferences
There are two preferences that need to be enabled for Sponsored Problem Reports
and Variances functionality:
• Problem Reports in Projects
• Variances in Projects
The preferences can be enabled at the site, organization, and/or container level (on
the project). Both preferences are under the "Change Management" category.
As a project creator or site administrator, use the preference manager to enable the
preferences.
Project Folders
By default the folder location is auto generated for change objects; when a new
sponsored object is created, it should be saved in the root folder of the project.
This default behavior can be changed. Use Object Initialization Rules
Administration to change the default.
Project Template
An organization can choose to configure suitable rules and policies that meet their
business needs using a project template. See the section Basic Administration for
further details.
Background
The cardinality of the AddressedBy link and the FormalizedBy link is driven by a
delegate infrastructure. The default implementation for out-of-the-box change
object types provided in Windchill 10.0 M20 or later is a delegate supporting 1-N,
N-1, or N-M cardinality. The later is only applicable if the change object
cardinality preferences are enabled. A new delegate is also available to support 1-
1 cardinality.
Scope/Applicability/Assumptions
• Assumes you have general knowledge about Java classes and concepts such as
class extension
• Assumes you have general knowledge about the xconf mechanism to create
properties.
Intended Outcome
After reading this, you should know how to create custom cardinality rules for
change requests and change orders, or change requests and change issues.
Solution
Solution: Create a custom class that extends a default delegate, and create an
xconf entry to register your custom delegate.
Prerequisite knowledge
To apply this best practice, you need to have an understanding of the following:
• Java class extension
• Xconfmanager
Solution Elements
Element Type Description
wt.change2. Interface Generalizable Interface
ChangeCardinalityDele- for cardinality rules
gate
wt.change2. Link class Supports 1-1
DefaultAddressedByDe- ChangeRequest2 to
legate ChangeOrder2 cardinality
wt.change2. Link class Supports 1-1
Customization Points
1. If you want to customize the cardinality for the AddressedBy2 link, then
you should create a new java class (your delegate) which extends the
DefaultAddressedByDelegate or the AddressedByDelegate
(depending on which existing functionality closest matches the behavior
desired)
public class YourCustomAddresssedByDelegate
extends DefaultAddressedByDelegate
{
/**
* Determines if the change request is 'properly
addressed'.
Default implementation of
* addressed by means that one change request can be
addressed
* by only one change notice and vice-versa.
* @param ChangeIssue
* @param ChangeRequest2
* @return void
* @throws WTException - If the cardinality is
* invalid, a ChangeException2
* should be thrown along with the reason why the
* cardinality is not valid.
*/
@Override
public void validateCardinalityConstraints(ChangeRequest2 cr,
ChangeOrder2 co) {
//YOUR RULES IMPLEMENTED HERE
}
Note
When defining this xconf configuration, it is important that the requestor
(in this case the ext.change2.YourChangeRequest2) is not an
abstract type, this is because the framework performs the lookup based on
a concrete class name (and it does not support hierarchical lookup of
types). The selector class, however, can be an abstract type. If you do not
register your delegate, then the default Windchill implementation would be
used instead of your delegate. This default implementation supports 1-N,
N-1, N-N (if the change object cardinality preference is enabled).
Modifying the cardinality of out of the box Windchill types:
For example, if you wanted to apply 1-1 cardinality between the
WTVariance and the WTChangeRequest2, you would have add the
following properties to xconf configuration:
<Service context="default" name=
"wt.change2.ChangeCardinalityDelegate">
<Option requestor="wt.change2.WTChangeRequest2" cardinality=
"singleton"
serviceClass="wt.change2.DefaultFormalizedByDelegate"
selector="wt.change2.WTVariance"/>
</Service>
ConcreteAssociationDelegate
ConcreteAssociationDelegate is used within
StandardChangeService2. It is obtained from the
Change2DelegateFactory.
There are many subclasses of ConcreteAssociationDelegate. Each one
takes two arguments: the two objects being linked. Each one returns the link
object that links the two objects. There is no mechanism for adding additional
values for attributes that belong on the link object, so this mechanism works best
for link objects that have not been customized with additional attributes.
One other complication with this delegate is that if you customize some of the
main classes, you may have to add properties file entries that may not seem
intuitively obvious.
Assume that you customize change order (that is, make a subclass of
wt.change2.WTChangeOrder2) in your myChange2 package within your
customization package and call it MyChangeOrder.
When looking up the appropriate subclass of
wt.change2.ConcreteAssociationDelegate, the following entry in
section 9 of wt.change2.change2.properties is being used when
linking the change order to a change request:
wt.services/svc/default/wt.change2.ConcreteAssociationDelegate/
wt.change2.WTChangeOrder2/wt.change2.WTChangeRequest2/
1=wt.change2.AddressedBy2Delegate/singleton
Scope/Applicability/Assumptions
This information assumes familiarity with the Resulting Objects table found on
the Change Task wizard. Knowledge regarding Life Cycle Transitions will also be
helpful.
Intended Outcome
To understand how to choose what state you want Resulting Objects to enter into
once the Change Notice is released.
Solution
In order to choose what state the Resulting Objects will go into when they are
released, you will need to select a Release Target for the Resulting Object on the
create or edit the Change Task wizard. If a Resulting Object has a Release Target
set during the time of the Change Notice release, the Resulting Object will go into
the state defined by the Release Target transition. Release Target Transitions can
be customized to include additional Change Management Transitions. See Create
Change Management Transitions on page 1179 for more information on
customization.
Prerequisite Knowledge
To complete this process you must have an understanding of the following:
• Concepts:
○ Change Task Resulting Objects Table
○ Life Cycle Transitions
○ Workflow Template Administration
• Properties:
○ wt.change2.changeTransitions
○ wt.change2.showAllChangeTransitions
• Preferences:
○ Change Management/Multiple Transitions on the Release Target Column
Note
New Windchill installations of release 10.1 M010 and beyond do not
require this modification.
Intended Outcome
The creation of change notices that are not templates are unaffected and keep the
current generated number sequence and life cycle template. The change notice
templates are generated with numbers that have 10 digits and use the “Basic” life
cycle template.
Solution
Update the change notice or task object initialization rule to conditionally
configure the number and life cycle template when the change notice or task
template attribute is set to true.
Prerequisite Knowledge
To achieve this result, you need to have an understanding of the following:
• XML
• Loading Windchill object initialization rules. For more information on how to
load and configure object initialization rules, see Loading Object Initialization
Rules.
Solution Elements
Element Type Description
Rule for Change Notice XML The rule for change
or task notice or task.
Procedure
When setting the argument for an attribute value in which the change notice or
task template value should be different than for the change notice or task creation,
use the wt.rule.algorithm.BooleanBranch value algorithm and test if
Limitations
It is not possible to configure the number attribute to be empty for change notice
or task template and generated for change notice or task because the template
attribute is not set until the create wizard is submitted. Instead, it is recommended
to use a generated sequence for both the change notice or task template and
change notice or task if a generated sequence number is required for creation of
change notice or task.
Sample Code
Updated object initialization rules (OIR) in file
ChangeMgmtInitRules.xml:
Change notice or task Regular Change
template notice or task
Life cycle template Basic Change Notice Life Cycle
Number 10-digit number 5-digit number
<!-- set the lifecycle -->
<AttrValue id="lifeCycle.id" algorithm="com.ptc.core.foundation.
lifecycle.
server.impl.LifeCycleTemplateAttributeAlgorithm">
<!-- if (template.templated) -->
<Value algorithm="wt.rule.algorithm.BooleanBranch">
<!-- test this value -->
<Attr id="template.templated"/>
<!-- if true -->
<Arg>Basic</Arg>
<!-- if false -->
<Arg>Change Notice Life Cycle</Arg>
</Value>
</AttrValue>
<Value algorithm="wt.rule.algorithm.BooleanBranch">
<!-- test this value -->
<Attr id="template.templated"/>
<!-- if true -->
<Arg>{GEN:wt.enterprise.SequenceGenerator:WTCHANGEORDERID_
seq:10:0}
</Arg>
<!-- if false -->
<Arg>{GEN:wt.enterprise.SequenceGenerator:WTCHANGEORDERID_
seq:5:0}
</Arg>
</Value>
</AttrValue>
Background
The term replicated object defines a non-modifiable object that is copied, or
replicated, from a different Windchill installation. Replicated objects are by
importing a ZIP file with the Received Delivery Management utility. Replicated
objects are subject to a special mechanism called an administrative lock that
prevents them from being modified on the importing system.
Under normal circumstances a replicated object could not be added as a resulting
object to a change task because the change process would not be able to update its
life cycle state. If such an attempt is made, then the following error message is
given when the change notice is completed:
In some circumstances to be able to add a replicated object that has already been
released to a change task (for example, as a new component of an assembly) is
required. It may also be required to add an effectivity value to the replicated object
when it is used a resulting object.
Scope/Applicability/Assumptions
To complete this customization, you must be familiar with the following:
• Creating change tasks
• Adding resulting objects
• Assigning effectivity values
Solution
Customize Windchill to allow replicated objects as change task resulting objects,
and prevent the change process from attempting to promote replicated objects to a
Released state.
1. Prerequisite Knowledge
To complete this process, you need to have an understanding of the following:
• Setting a system property
• Creating a custom life cycle template
• Creating an import life cycle mapping
Background
Business rules can be executed using the workflow and the results are displayed
on a workflow task. The change notice workflow, for example, executes the
Changeable Pre-Release rule set for the Audit Change Notice task and again prior
to releasing the resulting objects on the change notice. Users working on or
reviewing Change Tasks may want to get feedback before the Change Notice
Audit task runs, to verify that there are no conflicts before completing the task.
Scope/Applicability/Assumptions
This best practice provides steps to define a new action on the Change Notice
details page to execute a set of business rules and display the results. In order to
configure business rules see Customizing Business Rules on page 1221.
Prerequisite Knowledge
To apply this best practice you need to have an understanding of the following:
• Basic development involving HTML forms, JSP, and XML.
• The actions framework in the Windchill client architecture.
• The MVC component framework in the Windchill client architecture.
• The management of RBINFO file customizations.
• The Business Rules and how to execute business rules.
The Related Documentation on page 1201 section includes references to many or
all of these subjects.
@ComponentBuilder("CustomBusinessRulesResultsTable")
public class CustomBusinessRulesResultsTable extends
AbstractBusinessRulesResultsTable {
/**
* {@inheritDoc}
*/
@Override
public RuleValidationResultSet
getRuleValidationResultSet(NmCommandBean commandBean)
throws WTException {
RuleValidationResultSet resultSet = new
RuleValidationResultSet();
logger.debug("Get context object.");
NmOid contextOid = commandBean.getActionOid();
if(contextOid.isA(WTChangeOrder2.class)) {
logger.debug("Context object is a change notice.");
return resultSet;
}
}
Define Actions
• Define Business Rules Results Action
Define a new action in <Windchill>/codebase/config/actions/
custom-actions.xml to launch a popup window that displays the
business rules results.
<objecttype name="customBusinessRules"
resourceBundle="com.custom.customClientActionsRB">
<action name="customBusinessRulesResultWizard">
<command windowType="popup"/>
</action>
</objecttype>
The new action requires new action properties defined in a custom resource
file. See Action Framework for Client Architecture for more details on
defining new actions. The following is an example of properties configured for
the custom action:
@RBEntry("View Rule Conflicts")
@RBComment("Title of the wizard that displays business
rules results")
public static final String PRIVATE_CONSTANT_0 =
"customBusinessRules.customBusinessRulesResultWizard.
description";
@RBEntry("width=940,height=600")
@RBPseudo(false)
@RBComment("DO NOT TRANSLATE")
public static final String VIEW_CONFLICTS_MOREURLINFO =
"customBusinessRules.customBusinessRulesResultWizard.
moreurlinfo";
• Define Business Rules Results Table Step Action
<jca:wizard buttonList="OkCancelWizardButtons">
<jca:wizardStep action="customBusinessRulesResultStep"
type="customBusinessRules"/>
</jca:wizard>
<%@include file="/netmarkets/jsp/util/end.jspf"%>
Limitations
The execution of Business Rules against large data sets may take longer to
complete than is normally expected from an on-demand action. In these cases it
may be better to execute the Business Rules as part of a workflow process.
Sample Code
The execution of Business Rules against large data sets may take longer to
complete than is normally expected from an on-demand action. In these cases it
may be better to execute the Business Rules as part of a workflow process.
Background
In prior releases change object associations were prescriptive in that problem
reports can associate to a change request and change requests to a change notice.
The supported API’s for closing the change objects are also specific to the
supported relationships. Flexible change process associations now allow for
configurable change object associations. Updated APIs are now available to fully
support flexible change process associations.
A change object is considered closed when the resolution date and resolved state
(i.e. Canceled or Resolved) are set on a change object. The two ways to close
change objects are forced and synchronized closure. Synchronized closure is when
a change object listens for an event and checks to see if it can close itself. Forced
closure is when a different change object’s workflow process closes another
related change object, forcing the state and resolution date to be set. For most
cases synchronized closure is a better practice as this technique avoids dead lock
and stale object issues that can sometimes occur when using forced closure for
change objects having their own workflow process.
Scope/Applicability/Assumptions
The scope of this information is to outline recommendations for supporting
closure of change object associations using flexible change links.
Intended Outcome
The intended outcome of this information is to help provide guidance on how to
configure workflows to work with flexible change process associations.
Solution
There are APIs and Change Events available to support closure of Change Objects
associations using flexible links.
The Related Information on page 1209 section includes references to the APIs and
code samples.
Prerequisite Knowledge
To complete this process you must have an understanding of the following
• Basic development involving JAVA
• Defining workflow expressions
1. Select the workflow template Properties link. Go to the Variables tab and add a
new boolean variable named handlesClosure with the default value set to
true.
4. Add a new Expression between Synchronize and Set State Resolved. Set its
name to “Set Resolution Date”.
5. Update “Set Resolution Date” to set the resolution date on the change object.
com.ptc.windchill.pdmlink.change.server.impl.WorkflowProcessHelper.
setResolutionDate(primaryBusinessObject);
6. If force closure is required for the change process a new Expression can be
added after “Set State Resolved” to close either the parent or child
Additional considerations are required if the rules are not defined in the direction
of closure. Consider the following changes to the rule definitions:
Role A (Parent) Role B (Child) Owner Role
Related Information
Sample Code
Example change object workflow templates are provided within Windchill. They
can be found by navigating to Site ▶ Utilities ▶ Workflow Template Administration.
Scope/Applicability/Assumptions
The scope of this information is to outline recommendations for creating a Query
Builder Report that displays Flexible Change Associations to replace a report
displaying the Legacy Change Associations (wt.change2.AddressedBy2 or
wt.change2.FormalizedBy).
Intended Outcome
The intended outcome of this information is to help provide guidance on how to
create a report template that uses Flexible Change Links to display Flexible
Change Associations.
Solution
New link types are available to support a Query Builder Report Template for
associated Change Objects using Flexible Change Links.
Prerequisite Knowledge
To complete this process you must have an understanding of the following:
• Flexible Change Links
• Associated Change Objects
• Report Templates
• Change Objects
Solution Elements
Element Type Description
wt.change2. Class Abstract link for flexible
FlexibleChangeLink associations between two
FlexibleChangeItem
objects.
FlexibleChangeItem
objects include Problem
Reports, Variances,
Change Requests, and
Change Notices.
wt.change2. Class Link for flexible process
Existing Report
The following example represents a report you currently have that displays
Change Requests associated to Problem Reports through the Formalized By link.
2. Select the Tables and Joins tab. Click the Add button. Search and select
Change Process Link, then click OK.
4. Click the Add button again and this time select Change Request and click OK
5. Click and hold the yellow box in the bottom right corner of the Problem
Report box. Drag and drop over the Change Process Link Box. This should
bring up the Create Join Wizard.
7. Create another join between Change Request and Change Process Link.
8. Select Role B Object Ref (from Change Process Link) and click OK
10. Add the columns you would like to see on the report.
Intended Outcome
After going through this information, you should be able to start using the rules
that are provided with Windchill 10.1 M010, or you should be able to create
custom business rules for your change process.
You will then be able to use business rule sets and rules to validate that the objects
are valid to be processed.
Prerequisite knowledge
To apply this information, you need to have an understanding of the following:
• Basic development involving Java and XML
• The management of Windchill properties
• See the section Business Rules in the Windchill Help Center for more
information.
Solution Elements
Element Type Package Description
BusinessRuleSet Java class wt.businessRules A BusinessRuleSet
instance is the
configuration used
to navigate a set of
business rules for a
container.
BusinessRule Java class wt.businessRules BusinessRule will
hold the
information about
the rule to be
executed. Each
Here is another example of how you might want to set up a rework loop in the
Promotion Request Approval Process. The Business rule is executed in the OR
conditional. If it fails, then an email is sent and the Rework Promotion Request
task appears.
The selector is the relationship key which is used to look up the relationship
delegate instance. The relationship key naming convention is to use the link class
name but is not a requirement. Note that if the relationship delegate returns the
links for the relationship, then the role B objects of the links will be used as the
seed objects. The target link role can be optionally specified in the
BusinessRuleSetBean or RuleValidationCriteria. See the Javadoc
for BusinessRuleSetBean for details on how to specify the relationship for a
business rule set and current supported relationship delegates.
The following table shows the default delegates that are provided in a standard
Windchill installation:
Relationship Relationship Delegate Description
wt.change2. com.ptc.core. Gets the affected object
AffectedActivityData businessRules. links of the primary
relationship. business object if it is a
AffectedObjectsRelation- change notice or change
shipDelegate task.
wt.change2. com.ptc.core. Gets the affected object
ReportedAgainst businessRules. links of the primary
relationship. business object if it is a
AffectedObjectsRelation- problem report or
shipDelegate variance.
wt.change2. com.ptc.core. Gets the affected object
RelevantRequestData businessRules. links of the primary
relationship. business object if it is a
AffectedObjectsRelation- change request
shipDelegate
Note
As of the 11.0 release, the Promotion Request supports the Attribute Rule and
the Check Out rule. The Change Notice supports any rule.
Returning Results
The single validation result is generated for each target object that is evaluated is
combined into an aggregated set of validation results
(RuleValidationResultSet). The RuleValidationResultSet may
contain only partial results if there are failures during the execution of the
Limitations
The execution of business rules in Windchill release 10.1 M010 is a single
threaded operation.
Sample Code
The following is an example of the workflow conditional syntax in the delivered
Change Notice workflow template. The workflow conditional makes a call to the
business rules engine for the CHANGEABLE_PRE_RELEASE business rule set.
The CHANGEABLE_PRE_RELEASE business rule contains the CHECKOUT_
RULE and RELEASE_TARGET business rules.
Routing Expression
result = "NOT_READY";
com.ptc.core.businessRules.engine.BusinessRuleSetBean[]
ruleSetBeans =
new com.ptc.core.businessRules.engine.BusinessRuleSetBean[] {
com.ptc.core.businessRules.engine.BusinessRuleSetBean.
newBusinessRuleSetBean("CHANGEABLE_PRE_RELEASE", "wt.change2.
ChangeRecord2")
};
if ( !resultSet.hasResultsByStatus(com.ptc.core.businessRules.
validation.
RuleValidationStatus.FAILURE)) {
result = "PROCEED";
}
else {
//This line of code will start exception handling for the
business
rules that failed
businessRulesResultSetGlobal = wt.businessRules.
BusinessRulesHelper.
serialize(resultSet);
preReleaseConflictsMsg = new wt.util.WTMessage("com.ptc.
windchill.
enterprise.change2.change2ClientResource", com.ptc.windchill.
enterprise.
change2.change2ClientResource.BUSINESS_RULES_PRERELEASE_
VALIDATION_MSG,
null).getLocalizedMessage();
preReleaseConflictsMsg = preReleaseConflictsMsg + "\n" +
resultSet.
getFailedRulesMessage(java.util.Locale.getDefault());
}
Note that if the validation results are not successful, the attribute
businessRulesResultSetGlobal is set to the serialized string of the
validation result set. The “View Conflicts” report link will show up on the “Audit
Change Notice” and “Resolve Release Conflicts” workflow task pages.
Examples
If we had a part in Product 1 that was a Resulting Object, the part would have to
have a part name less than 10 characters, and it could not be checked out.
If we had a document in Product 2 that was a resulting object, then there are no
rules for it. This is because there are only rules for Parts.
Solution
Create two business rule sets. One of the business rule sets has business rules that
are required to continue or complete the workflow process. The second business
rule set has business rules that you want reported but are not required to continue
the workflow process. Having two separate business rule sets will allow you to
configure a workflow process that allows you to call both or one of the business
rule sets at different points in the workflow process. The workflow process can be
configured to execute all required and non-required business rule sets for a
workflow task such as the Change Notice Audit task.
This task is configured to continue once it has been completed. For more
information, see Execute All Required and Non-Required Business Rule Sets on
page 1244. A second workflow task in the process can be configured to execute
only the required business rule sets. This task will continue to be generated until
all errors are resolved. For more information see Execute Required Business Rule
Sets on page 1246.
Example
The following example uses Example Use Case 1 from above to show how to
create two sets of rules to execute in a change notice workflow process. The
example shows how to configure a set of rules to be required to proceed in the
workflow process and a second set of rules that are not required but shown as
informational data.
Create a Link for the Attribute Rule and Non Required Rule
Set
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE BusinessRuleLink SYSTEM "standardX20.dtd">
<BusinessRuleLink>
<ObjectID><localId>wt.businessRules.BusinessRuleLink:10003
</localId></ObjectID>
Create Link for the Target Rule and Required Rule Set
<?xml version="1.0" encoding="UTF-8" ?>
if (wt.change2.ChangeHelper2.isTrackingChange((wt.inf.container.
WTContained)
primaryBusinessObject)) {
result = "Revisioning Enabled";
}else {
if ( !resultSet.hasResultsByStatus(com.ptc.core.businessRules.
validation.RuleValidationStatus.FAILURE)) {
result = "PROCEED";
}
else {
businessRulesResultSetGlobal = wt.businessRules.
BusinessRulesHelper.
serialize(resultSet);
preReleaseConflictsMsg = new wt.util.WTMessage
("com.ptc.windchill.enterprise.
Prerequisite Knowledge
To perform this task, you need to have an understanding of the following:
• General knowledge of using DTD for creating XMLs
• Validating the XML based on the DTD
• An understanding of the Import Export Framework. For more information, see
Import Export Framework on page 2390
Process
You can use any text editor to author an XML file for business rule objects.
Solution Elements
Element Type Description
standardX20.dtd DTD DTD for load files.
Location: <Windchill>\
loadXMLFiles
businessRules.dtd DTD Modularized business rule DTD.
Location: <Windchill>\codebase\
registry\ixb\dtds\
standardX20.dtd\
businessRules.dtd
DTD Definition
The business rules DTD is part of the standardX20.dtd definition. The
definition of the DTD can be located at: <Windchill>\codebase\
registry\ixb\dtds\standardX20.dtd\businessRules.dtd
Note
If invalid resource key is specified the name or description field will show
non-localized value of the field. In the above example if the resource bundle
did not exist, name is displayed as
com.ptc.windchill.enterprise.change2.change2ClientRe
source:CHECK_OUT_VALIDATOR_RULE_NAME
BusinessRule
A BusinessRule object holds the information about the Rule to be executed.
Each Rule may have unique configuration requirements associated to it. A key
and the container should be unique for creating BusinessRule objects.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE BusinessRule SYSTEM "standardX20.dtd">
<BusinessRule>
<ObjectID><localId>wt.businessRules.BusinessRule:45346</
localId></ObjectID>
<objectContainerPath>/</objectContainerPath>
<key>IXBBusinessRule1_key</key>
<name> com.ptc.windchill.enterprise.change2.
change2ClientResource:
CHECK_OUT_VALIDATOR_RULE_NAME</name>
BusinessRuleSet
A BusinessRuleSet instance is the persistence configuration of a set of
Validation Rule. Typically holds the rules configured to be executed for the
container. A key and the container should be unique for creating
BusinessRuleSet objects.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE BusinessRuleSet SYSTEM "standardX20.dtd">
<BusinessRuleSet>
<ObjectID><localId>wt.businessRules.BusinessRuleSet:45345</
localId></ObjectID>
<objectContainerPath>/wt.inf.container.OrgContainer=
PTC/wt.pdmlink.PDMLinkProduct=GOLF_CART</objectContainerPath>
<key> IXBBusinessRuleSet1_key </key>
<name> com.ptc.windchill.enterprise.change2.
change2ClientResource:
CHANGE_PRE_RELEASE_RULESET_NAME </name>
<description> com.ptc.windchill.enterprise.change2.
change2ClientResource:
CHANGE_PRE_RELEASE_RULESET_DESC</description>
<enabled>true</enabled>
<overridable>true</overridable>
</BusinessRuleSet>
BusinessRuleLink
A ObjectToObject binary link holding the references to
BusinessRuleSet and Rules.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE BusinessRuleLink SYSTEM "standardX20.dtd">
<BusinessRuleLink>
<ObjectID><localId>wt.businessRules.BusinessRuleLink:356747
</localId></ObjectID>
<ruleSet><ObjectReference><localId>wt.businessRules.
BusinessRuleSet:45345
</localId></ObjectReference></ruleSet>
<rule><ObjectReference><localId>wt.businessRules.
BusinessRule:45346
</localId>
</ObjectReference></rule>
Note
The zip file must be located in a folder path within the <windchill>
directory.
2. Create the XML load file to load the generated zip file created in step 1.
Here is an example:
<?xml version="1.0"?>
<!DOCTYPE NmLoader SYSTEM "standardX20.dtd">
<NmLoader>
<csvExecuteImport handler="wt.load.LoadImport.executeImport">
<csvimportFilename>loadFiles/ixbImport/businessRulesObjects.zip
</csvimportFilename>
</csvExecuteImport>
</NmLoader>
3. Using a Windchill shell, execute the following load command to load the
business rules objects.
windchill wt.load.LoadFromFile -d <PATH>\loadFileName
where loadFileName refers to the file created in step 2. Executing the
command stores the business rule objects in the database, ready to be
configured.
Note
Because the key and a container forms the BusinessRule object
uniqueness, both cannot be updated once created even if the ability to update
existing rules is enable.
To delete a business rule link, the business rule set and business rule that it links
need to be specified.
Examples
• Deleting a business rule
windchill wt.businessRules.DeleteBusinessRuleObjects
"BusinessRule:keyToDelete:/
wt.inf.container.OrgContainer=Org Name/
wt.pdmlink.PDMLinkProduct=Product Name"
• Deleting 2 business rule sets
windchill wt.businessRules.DeleteBusinessRuleObjects
"BusinessRuleSet:keyToDelete:/
wt.inf.container.OrgContainer=Org Name/
wt.pdmlink.PDMLinkProduct=Product Name"
"BusinessRuleSet:anotherKey:/
wt.inf.container.OrgContainer=Org Name/
wt.pdmlink.PDMLinkProduct=Product Name"
• Deleting a business rule link
windchill wt.businessRules.DeleteBusinessRuleObjects
"BusinessRuleLink:businessRuleSetKey:/
wt.inf.container.OrgContainer=Org Name/
wt.pdmlink.PDMLinkProduct=Product
Name:businessRuleKey:/wt.inf.container.OrgContainer=
Org Name/wt.pdmlink.PDMLinkProduct=Product Name"
Examples
The following XML defines a set of business rule objects which implement the
checkout rule.
Attribute Rule
The attribute rule validates that the specified attribute rule configuration for an
object type is valid. The object type is the only required input for an attribute rule
configuration. The object type should be a wt.fc.Persistable type object.
For example com.ptc.Waiver is a soft type of
wt.change2.WTVariance.
<configs>
config name="objectType" value="com.ptc.Waiver"></config>
Note that the system locale is used for the format of the dates and timestamps in
the attribute condition.
Examples
If you have a specific soft type of a part, and it has an attribute called weight to
represent how heavy the part is. Before releasing parts that have a weight, you
want to ensure that a weight is set to a reasonable figure. In order to do this, you
want to construct a business rule to verify that the weight attribute falls within the
range 1-100.
Examples
The following XML defines a set of business rule objects which implement the
Release Target rule.
Examples
If you need to change an assembly that has many child parts. However, before you
change the assembly, you want to ensure that all of the children are in the
Released state, or are in the Releasedstate as a result of this change. You also want
to ensure that all of the child parts are up-to-date, so you want to ensure that none
of the children parts had become Obsolete at some point in time. To configure
this, you could create the following business rule objects.
1269
Customizing Change Management
Workflow Process Templates
Synchronization robots are a critical part of the Change Management workflow
process template examples. Originally, these robots were developed as pure
expression robots. However, use of normal expression synchronization robots
causes very heavy Oracle activity, resulting in frequent Oracle redo log turnover.
At Release 5.1, therefore, these robots were updated to use object or class event
synchronization in conjunction with an expression.
These change affect only out-of-the-box example workflow process templates in
loadFiles\ChangeManagement.csv. If you use these templates but have not
customized them, simply delete the existing templates and load the modified ones.
If you have customized the out-of-the-box workflow process templates, you
should manually incorporate the changes, as described in the remainder of this
section, into your customizations to take advantage of the improved performance.
If your own expression synchronization robots are problematic, you should
manually incorporate changes similar to those described in this section.
Following are the Change Management workflow process templates that have
been enhanced to improve system performance:
• Change Issue Process
• Change Request Process 2
• Change Investigation Process
• Change Proposal Process
• Change Analysis Process
• Change Order Process
• Change Activity Process
Before Release 5.1, the expression logic performed the following actions:
1. Determine which children objects are applicable to the synchronization. For
example, in the Sync on Change Activities robot, all the change activities
related to the change order are relevant.
2. Determine the life cycles states of all the relevant objects.
3. Based on the result of step 2, either continue holding or move on to one of
several possible activities that follow in the workflow.
Release 5.1 includes the following changes to this logic:
The expression synchronization robot has been replaced with a conditional router
followed by the sync robot. The sync robot has been changed to a new class event
synchronization robot. The class differs depending on the particular
synchronization robot, but the event is always STATE CHANGE. The conditional
router contains exactly the same logic as the expression in the object event
subscription robot. The purpose for this conditional router is to immediately check
whether the state has already been reached. This helps avoid the race condition of
the state being achieved prior to the instantiation of the synchronization robot.
This change resulted in the following improvements:
The synchronization expression is executed only when an object in the proper
class has changed state. As a result, the expression is executed only when there is
a chance that the states of all related objects are in synchronization.
New Installations
A new Windchill installation will include the new Change Management workflow
process templates. Be sure to load the "Change Management lifecycles and
workflows" during the initial database load.
For further information about loading data, see the Windchill Installation and
Configuration Guide.
Existing Installations
If you are not concerned about overwriting existing demo workflow process or life
cycle templates, you can simply initiate "java wt.load.Demo " and answer "no" to
all questions except "Change Management lifecycles and workflows" (see the
Windchill Installation and Configuration Guide for further information about
loading data). You can ignore errors regarding the "Change Items" Domain and
the example projects. However, to avoid these errors, remove all sections from
ChangeManagement.csv except those for the Change Management workflow
process templates and life cycle templates.
If you do not want to overwrite the existing demo workflow process templates,
PTC recommends that you perform one of the following options before loading
the new workflow and life cycle templates:
• Rename the existing workflow and life cycle templates using the Workflow
Administrator and Life Cycle Administrator.
• Rename the new workflow and life cycle templates by manually editing the
ChangeManagement.csv file.
After loading the Release 5.1 workflow process and life cycle templates, you can
restore them to their original state one at a time by clicking Delete Latest Iteration
from the Workflow Administrator or Life Cycle Administrator page.
Code Impacted
The following code has been impacted by the enhancements:
• The workflow processes in loadFiles\ChangeManagement.csv, including the
changes described in this section.
• wt.change2.process.ProcessHelper – A new, overloaded version of the
checkRequestFinished method has been added, which takes a change request
and checks the state of the passed object.
• wt.change2.StandardChangeService – The methods saveFormalizedBy and
deleteFormalizedBy now emit the events ISSUE_FORMALIZED and ISSUE_
UNFORMALIZED, respectively.
• wt.admin.AdminEventResource – The ISSUE_FORMALIZED and ISSUE_
UNFORMALIZED events were added to this resource bundle (and all of its
language variants).
• wt.workflow.robots.synchEventResource – The ISSUE_FORMALIZED and
ISSUE_UNFORMALIZED events were added to this resource bundle (and all
of its language variants).
• wt.notify.notify.properties – The ISSUE_FORMALIZED and ISSUE_
UNFORMALIZED events were added to this property file.
The customized workflow should also have a similar locking mechanism before
including the task for review.
The second conditional does the actual promotion of the targets and has code like:
wt.maturity.PromotionNotice pn =
(wt.maturity.PromotionNotice)primaryBusinessObject;
try
{
wt.maturity.MaturityServerHelper.service.promoteTargets (pn);
result="Approved";
}
catch (wt.maturity.MaturityException me)
{
result="Rejected";
}
Background
During the Promotion Request review and approval process, it is not uncommon
for the participants to uncover issues associated with the promotion candidates.
Rather than rejecting the Promotion Request, the process can be more efficient
with the introduction of a rework loop. This rework loop allows the creator of the
Promotion Request to review the comments, make appropriate adjustments to the
promotion candidates, and have the workflow automatically refresh the Promotion
Request for another review and approval.
It is also good practice to avoid sending promotion targets for approval when the
result will be a validation error. The rework loop contains this validation based on
the current iterations of promotion targets or the refreshed iterations if Automatic
Refresh is enabled.
For companies that use the Promotion Request as a "Gate Review" for production,
a best practice is to switch the revision labels for objects from a numeric series to
an alphanumeric series. With a proper life cycle design, such a gate state can be
modeled that achieves the desired target state and automatically revises the
promotion candidates to the initial revision label of the new revision series.
Scope/Applicability/Assumptions
These instructions assume a pre-existing knowledge of modifying workflow
processes and how to call Windchill methods within the workflow.
Intended Outcome
The expectation is that you will be able to add the auto-refresh or the automatic
revise functionality to your customized workflows.
Prerequisite knowledge
To achieve this result, you need to have an understanding of the following:
• Basic Java development
• Workflow process modification including tally expressions and robot
expressions
• The management of resource bundle file.
• Windchill Preference Management utility
Note
The workflow process templates provided out-of-the-box should not be
modified directly. These process templates should be renamed prior to
modification.
Solution Elements
Element Type Description
wt.maturity. method This method call can be added to a
MaturityServerHelper. workflow expression that will unlock
service.unlockTargets the promotion targets in this case for
(pn) rework. The result of this is the
promotion targets will be at the state
they were at, at the moment the
promotion request was created.
Unlocking the promotion targets may
allow the user assigned to rework to
perform updates on the objects (subject
to access control).
wt.workflow.work. class This class is used to tally votes of a
WfTally workflow task. For example if a task is
assigned to the approval role multiple
users could receive that task and vote
differently. This class provides
methods that define which route to take
based on if ‘all have to vote for that
In this example a rework loop has been added. The loop begins at the Approve
Promotion Request task. Members of the Promotion Approvers receive this task.
An addition route has been added to the Approve Promotion Request task called
Rework.
In this example, a tally expression is defined that determines, based on all the
approvers’ votes, which route to take.
Vector v = new Vector();
v.addElement("Approve");
v.addElement("Reject");
v.addElement("Rework");
Vector vResult = wt.workflow.work.WfTally.any(self, v);
if( vResult.contains("Rework")) {
result = "Rework";
} else if ( vResult.contains("Reject") ) {
result = "Reject";
}else {
vResult = WfTally.all(self,v);
if( !vResult.isEmpty() ) {
FIT Table
The following fit table describes how the Latest iteration Refresh preference
affects automatic refresh.
Promotable Is Promotion Latest iteration Eligible to be
Target refresh Refreshed
preference
value
part_1 N/A Do Nothing false
part_2 Y Refresh promotion true
candidates
part_3 Y All true
part_4 N Refresh promotion false
candidates
part_5 Y All true
reviseValidationMsg= com.ptc.windchill.enterprise.maturity.
validators.
PromotionTargetsReviseValidator.getReviseResultSetMessage(set,
locale);
if (!reviseValidationMsg.isEmpty() )
result="Partial";
else
result="Full";
}
catch( Exception wte )
{
wte.printStackTrace();
}
The method revisePromotables(pn, pn.getCreator(), locale);
performs the revision of the promotion objects following the preferences defined
above in the Solution section.
Note
If promoting CAD Documents and Parts together, if the revise disqualifies
either the part or CAD document, the objects will not be revised together and
will need to be correctively fixed by the promotion request creator (or another
user) after promote.
Workflow Template
Here is the expanded promotion notice workflow template with validation.
A conditional has been added to perform the above checks. An email is sent to the
creator with a list of promotion targets that cannot be promoted (if any). If some
targets of the Promotion Request cannot be promoted, the Promotion Request is
sent back for rework where the creator can either submit or reject. If all targets are
valid the promotion request is sent for approval.
Note
Declare the user defined event as a new variable. For example, if the total
number of resources available in the synchEventResource.java
file are 39, declare MY_EVENT as the 40th variable.
public static final String PRIVATE_CONSTANT_<next_count>=
“*/<Classpath>/<Custom_Event>”;
wt.workflow.engine.WfEngineServerHelper.service.
emitCustomObjectEvent ("MY_EVENT",
primaryBusinessObject, valueMap);
Where:
• MY_EVENT is the customized event as created above. Alternatively, any event
selected in the Event dropdown list in the Synchronization robot properties
window would be substituted in its place.
• PrimaryBusinessObject is the object on which we want to emit an
event. In other words, the object on which the Synchronization robot is
listening for MY_EVENT (the customized event).
Note
A customized event can be emitted from any customized code or from an
expression robot.
Process Overview
Configuring the workflow task page consists of the following steps:
1. Identify the PBO object type that you want to customization.
2. Identify the Workflow task type that you want to customize.
3. Identify the tables which should be rendered in the workflow task and their
sequence.
4. Identify the PBO actions that need to be rendered in the task info page and
their sequence.
5. Identify the PBO attributes that must be rendered.
6. Identify the tabs to be on the workflow task page and where the tables and
actions must be rendered.
7. Create the load file for the task form template object in the proper format and
load the file.
8. Configure the workflow task to use the loaded task form template.
Identify PBO
Identify the PBO object type that you want to customize. Any
lifecyclemanaged object can be used as a PBO. Hard types and soft types
are supported (WTPart, WtDocument, Agenda, Meeting, EPMDocument, etc).
You need to identify the full class name of the PBO.
2. Configure the identified tables above into a workitem task action model.
Define a new action in a custom actions file for the component (e.g. Affected
Data table) to display in the configurable workflow pages. The component
name needs to be "workflowTask.pbo", the component id needs to be
passed as pboCompId in the urlParams and the useTypeBased needs
to have the value based on the finding in previous step.
For example:
<action name="TestAffectedData"
resourceBundle="wt.workflow.worklist.worklistResource" >
<component name="workflowTask.pbo"
urlParams="pboCompId=changemanagement.
import com.ptc.core.ui.validation.
DefaultUIComponentValidator;
import com.ptc.core.ui.validation.UIValidationCriteria;
import com.ptc.core.ui.validation.UIValidationKey;
import com.ptc.core.ui.validation.UIValidationResult;
import com.ptc.core.ui.validation.UIValidationResultSet;
import com.ptc.core.ui.validation.UIValidationStatus;
import com.ptc.netmarkets.util.beans.NmCommandBean;
import com.ptc.core.meta.common.TypeIdentifier;
import com.ptc.windchill.enterprise.history.validators.
LifecycleHistoryNavValidator;
@Override
protected boolean isComponentValidFor(UIValidationKey
validationKey,
UIValidationCriteria validationCriteria, WTReference pboRef) {
return false;
}
}
4. Configure the validators in the appropriate .properties files. The following
code sample continues the example about PboMaturityHistory. Add
these actions in the Workitem-service-properties.xconf file.
...
<Option cardinality="singleton" requestor="java.lang.Object"
serviceClass="com.ptc.windchill.enterprise.workitem.validators.
WorkflowTaskPboMaturityHistoryValidator"
selector="PboMaturityHistory"/> [Option cardinality="singleton"
requestor="java.lang.Object" serviceClass=
"com.ptc.windchill.enterprise.workitem.
validators.TestAffectedDataValidator" selector="TestAffectedData"/>
...
<model name="ConfigurableTask.wt.part.WTPart">
<submodel name="more part actions"/>
</model>
<model name="ConfigurableTask.wt.change2.WTChangeIssue">
<action name="view" type="object"/>
<action name="edit" type="problemReport"/>
<action name="editModifyContentOnly type="problemReport"/>
</model>
</actionmodels>
<action name="workflowTaskPboAttributes"
resourceBundle="wt.workflow.worklist.worklistResource">
<component name="workflowTask.pbo"
urlParams="pboCompId=workflow.pbo.attributes" />
<includeFilter name="configurableTypeBaseFilter"/>
</action>
</objecttype>
<!-- MULTI OBJECT EDIT ACTIONS END-->
To view this action you must create the layout by selecting “Information Page –
Workflow Task attribute” and “workflowTaskPboAttributes“ to render this layout
on the task details page.
<WorkflowTaskTab>
<tabName>TestTab2</tabName>
<tabSetKey>infopage</tabSetKey>
<components>
[{"name":"workflowTaskPboAction","type":"workitem"},
{"name":"attributes","type":"workitem"},
{"name":"routingStatus","type":"workitem"}]</components>
<pboAction>[{"name":"checkin","type":"wip"}]</pboAction>
<sequence>2</sequence>
</WorkflowTaskTab>
</TaskFormTemplate>
2. To use the task form template to generate the task detail page, a preference
must be set.
Navigate to Utilities ▶ Preference Management ▶ Workflow ▶ Use task form
template to generate the task details page.
If you specify to render a particular custom activity variable (other than special_
instructions, instructions, or primaryBusinessObject) with the all_activity_
variables, the specified custom activity variable gets rendered twice.
Once the customizer has described and retrieved the property model (via the
workItemInfo.tag), they need to specify where on the page to render the
particular workflow activity variable's GUI component. This is done by including
the taskPanelValue tag, along with the new property model and the list of
variables to display at the desired location of the JSP. (Note: the list of variable
names must match the names listed for tags:workItemInfo. That is, if "all_
activity_variables" was specified, then this same name must be used to render the
GUI Components for "all_activity_variables.)
Render Examples:
<tags:taskPanelValue propertyModel="${propertyModel}"
attrs="variable_name"/>
<tags:taskPanelValue propertyModel="${propertyModel}"
attrs="special_instructions"/
<tags:taskPanelValue propertyModel="${propertyModel}"
attrs="all_activity_variables"/>
The following table lists the paths that can be used with tablePageLink:
PBO Path Available Function
Component
Affected End /netmarkets/jsp/change/ • Change Request-
Items affectedEndItemsTable.jsp WTChangeRequest 2
• Change Issue or Variance-
ChangeIssue
Affected and /netmarkets/jsp/changeTask/af • Change Task-
Resulting Items fectedAndResultingItems.jsp WTChangeActivity2
Attributes and /netmarkets/jsp/object/ • Change Request-
Attachments attribute s.jsp (no attachments WTChangeRequest 2
for CA) • Change Notice-
WTChangeOrder2
• Change Task-
WTChangeActivity2
• Change Issue or Variance-
ChangeIssue
• Promotion Notice-
PromotionNotice
Baselines /netmarkets/jsp/object/ • Change Request-
relatedBaselines.jsp WTChangeRequest 2
• Change Notice-
WTChangeOrder2
• Change Task-
WTChangeActivity2
Contexts /netmarkets/jsp/object/ • Change Request-
relatedContexts.jsp WTChangeRequest 2
<workItem:promotionObjects/
Notebook Table <workItem:notebook displayType="Table"/
Discussion Table <workItem:discussions
displayType="Table"/>
Routing History To display routing history for all activities:
Table <tags:routingStatus dispProcess="All"/>
Note
The display of the routing history table currently includes
the reassignment table as well. An SPR exists to allow the
routing history table to be displayed independent of the
reassignment history table.
Reassignment To display the reassignment history table as embedded and
Table expanded in the JSP:
<tags:reassignHistory showRH="Table"/>
Note
To get the Site5_wt.fc.WTObject_WfTask_default.jsp file
we have “template view” preference must be set.
<Option
serviceClass="com.ptc.windchill.enterprise.change2.handler.Defa
ultAutomateCreateChangeNoticeHadler"
selector="DefaultHandler" requestor="null"
cardinality="duplicate"/
</Service>
Prerequisite knowledge
To apply this knowledge, you need to have an understanding of the following:
• Knowledge of creating and modifying a workflow.
• Familiarity with change management concepts such as resulting data.
• Access to a system where the Refine and Review workflow transitions are
supported.
• That you have administrator access to the workflow and life cycle back end on
the Windchill application.
4. Next you must link the expression with the workflow so it is executed.
a. You can modify or add new arrows using the Action tool ( ).
b. Holding CTRL and drag arrows between states. In this example it is added
before the Change Notice is submitted.
5. Now that it is part of the Change Notice’s workflow execution, you must make
it a Refine or Review transition. You can do this by adding some code to the
expression. Double click the new Expression and then select the Expression
tab.
a. To add a Refine transition add the following expression code to the
transition:
wt.maturity.TransitionHandlerFactory.getInstance().transitionTar
gets
(primaryBusinessObject,wt.lifecycle.Transition.toTransition(“RE
WORK"),false);
wt.maturity.TransitionHandlerFactory.getInstance().transitionTar
gets
(primaryBusinessObject,wt.life
cycle.Transition.toTransition("REVIEW"),false);
Note
If you copy and paste the transition code out of Word and directly into
Windchill, Word will copy invalid quotes which are not valid for the java
compiler. To get around this, when adding your expression code, paste it
into a Notepad first, copy it from Notepad, then paste into the Windchill
Expression box.
7. Save your changes and then Exit the Change Notice Workflow window. Now
you have a working copy of the new workflow with a Review Transition.
You can use the same process to add Refine transitions.
5. Configure what you want the state to do if it is under the Refine transition.
Keep in mind this would likely be useful to use just after the Review has
occurred. Because of this, when the Change Notice is in Under Review state,
Scope/Applicability/Assumptions
This documentation assumes familiarity with:
• type attribute layouts
• creating new xconf entries
• using xconfmanager
• resource bundles
• defining variables in a workflow process
After you have done this, the attribute will now show up with the value defined by
the RBEntry annotation:
Note
If you are using a separate template for “Subject” then edit the following
template: <Windchill>\codebase\templates\
workNotification\GeneralSubject_<Locale>.html
Note
If you are using a separate template for “Subject” then edit the following
template: <Windchill>\codebase\templates\workflow\
DeadlineNotificationSubject_<Locale>.html
Note
If you are using a separate template for “Subject” then edit the following
template: <Windchill>\codebase\templates\
workNotification\NotificationRobotSubject_
<Locale>.html
Note
If you are using a separate template for “Subject” then edit the following
template: <Windchill>\codebase\templates\calendar\
DelegateNotificationSubject_<Locale>.html
In the above example, an email generated for notification will have of subject
consisting of the methods defined in the “Subject” template mentioned above.
Alternatively, individual methods within Windchill tags can be added within the
beginSubject and endSubject tags.
<SCRIPT LANGUAGE=Windchill>
<!-- beginSubject -->
</SCRIPT>
<SCRIPT LANGUAGE=Windchill>
<!-- getProcessName -->
</SCRIPT>
<SCRIPT LANGUAGE=Windchill>
<!-- getPrimaryBusinessObjectName -->
</SCRIPT>
<SCRIPT LANGUAGE=Windchill>
<!-- endSubject -->
</SCRIPT>
There are standard methods written for these notification types. These are listed
below.
Common Methods
• addText text="<value>"
• getActivityName
• getActivityVariable varName="<Variable Name>" (not
applicable for Notification Robot)
• getInitSubject
• getPrimaryBusinessObjectName
• getProcessName
• getProcessVariable varName="< Variable Name >"
Prerequisite Knowledge
To perform this customization you need to have an understanding of the
following:
• Basic development involving JAVA and properties.
Solution Elements
Element Package Type Description
ParticipantConfi- com.ptc.windchill. Interface The interface for
guration enterprise. the delegates
wizardParticipant. which control the
configuration display of the
wizard participant
selection table with
different
configurations.
DefaultParticipant- com.ptc.windchill. Class The default
Configuration enterprise. delegate for
wizardParticipant. displaying the
configuration wizard participant
selection table with
different
configurations.
PromotionPartici- com.ptc.windchill. Class The configuration
pantConfiguration enterprise.maturity. delegate for
configuration displaying the
promotion wizard
participant
selection table.
typedservice. xconf Participant
properties.xconf configuration
delegates are
registered in the
typed service
properties.
Override Display
To override the display of the participant selection picker in the change task or
promotion request wizard the DefaultParticipantConfiguration
delegate can be extended to provide the desired behavior. The promotion request
overrides some of the default display behavior which is implemented by the
PromotionParticipantConfiguration. To make use of the customized
participant configuration delegate it must be first registered in the
typedservice.properties for the type of object that the delegate is to be
used for. The typedservice.properties should not be directly updated
instead a custom typedservice.properties.xonf should be created to
register the delegate. Currently the supported types are promotion request, change
task and any sub types. The following is the example of a delegate registered for
the Promotion Request object.
<Service context="default"
name= "com.ptc.windchill.enterprise.wizardParticipant.
configuration.ParticipantConfiguration" >
<Option requestor="wt.maturity.PromotionNotice"
selector="wizardParticipantConfiguration"
serviceClass= "com.ptc.windchill.enterprise.maturity.
configuration.
PromotionParticipantConfiguration" />
</Service>
The following table describes specific display configurations which can be
overridden:
API Description Default Overridden
Behavior Behavior for
(Change Task) Promotion
Request
getWorkFlowTem- The work flow Looks up the life
plate process template cycle template
which is used to work flow process
define the template from the
displayed work selected object
flow roles for type in the wizard.
selection and the
resource pools
used to display the
list of participants.
getWorkflowRe- The resource pools The resource pools
sourcePools used to display the used to display the
list of participants list of participants
available for available for
Since both Approver and Reviewer roles are configured as fixed system selected
roles they are both hidden in the participants table.
Note
This process assumes familiarity with workflow processes for change objects
and workflow customization. The techniques described in this document are
limited to change object workflow templates.
Intended Outcome
Assume a case where a change task is created with three assigned participants
using the OOTB Change Activity Workflow template. When the change task is
first created its process page shows the following.
Creating rework tasks for all original team members may run contrary to a
company’s standard change process. For example, a change process may dictate
that only User 2, who originally performed the work, should be assigned to a
special “rework” role. And further, User 2 should be the only person assigned to a
rework task. The desired process page should show the following. This is only
possible by manually editing the process when using the OOTB Change Activity
Workflow template. A customized template is needed to automatically follow this
change process.
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
• Workflow Processes for Change Objects
• Workflow Template Administration and Customization
• Life Cycle Template Administration and Customization
• Object Initialization Rules Administration and Customization
• Enumerated Type Customization
• Basic Java programming
4. Double-click Rework Change Notice Task to open the editor and select the
Participants tab. Add the Rework Assignee role and remove the Assignee role.
This step can be skipped if a new role is not needed.
6. Add Java code to the Set Rework Assignee step to automatically obtain the
users that completed the prior work task and assign them to the change item
team for the rework task. For information on the helper methods that can be
called here, see the section: Java Helper Methods.
Example:
wt.project.Role reworkRole = wt.project.Role.toRole("REWORK_
ASSIGNEE");
wt.project.Role participantsRole = reworkRole;
java.util.Map<wt.project.Role, wt.fc.collections.WTSet>
roleToParticipantMap;
// Try to get participants from the rework activity.
roleToParticipantMap = com.ptc.windchill.pdmlink.change.server.
impl.WorkflowProcessHelper.getActivityParticipants(
// If the map is null then the rework activity has not executed yet.
if (roleToParticipantMap == null) {
participantsRole = wt.project.Role.toRole("ASSIGNEE");
7. When the Java code is complete select the Check Syntax button to check for
errors. Be sure to correct all errors before using the custom workflow
template.
8. Save the changes made to the “Custom Change Activity Workflow” template
and check it in.
* @throws WTException
*/
Scope
Supported tables for configuration are
• Resulting Objects table
• Change Notice summary table
Intended Outcome
This document describes on how to create a new component which is a variant of
resulting or change summary table.
Prerequisite Knowledge
To perform these customizations, you must have an understanding of the
following:
• Java programming language
• Creation of new actions, and action models. For more information, see Adding
Actions and Hooking Them Up in the UI.
• Adding xconf entries and running xconfmanager. For more information, see
Using the xconfmanager Utility.
Solution
This section contains an example of adding a variant of Resulting Objects or
Change Summary table. This process includes the following steps:
• Define a New Table Component on page 1352
• Define a Workflow Action for the New Component on page 1353
• Adding New Resource Bundle Entries on page 1355
• Add New Action to Workflow Task Components List on page 1355
• Build and Test on page 1356
Note
If the action model for the row object actions is not defined, the default action
model for the row object type is used.
For more information on creating custom xconf entries, see Compiling Custom
Classes.
Prerequisite Knowledge
To achieve the intended result you need to have an understanding of the following:
• Modifying and/or creating Workflow Templates.
• Working with expressions in workflow nodes using the Java Language
Note
If you want to use the new transition as part of a change process, you must
perform additional steps. For more information, see “Custom Change Process
Transitions” in the Windchill Help Center.
Modify TransitionRB.rbInfo
The follow example creates a new transition called “Reject”:
1. Locate the following file (or create it if it does not exist):
<Windchill>/wtCustom/wt/lifecycle/
TransitionRB.rbInfo
3. Build the runtime resource bundles for the customized packages by entering
the following command from a Windchill shell:
ResourceBuild wt.lifecycle.TransitionRB
Results
As a result:
• The new transition is added to the transitions that are available when you
create or update life cycles using the Life Cycle Administration utility.
• The new transition can be accessed programmatically.
• You can invoke the navigate() method to find the valid transitions
between states using that new transition:
WTKeyedMap rejectMap=new WTKeyedHashMap();
Set rejectSet = new HashSet();
State rejectState=State.toState("DESIGN");
rejectSet.add(rejectState);
rejectMap.put(<life_cycle_managed>, rejectSet);
WTKeyedHashMap returnMap =
(WTKeyedHashMap) LifeCycleHelper.service.navigate
(rejectMap,
Transition.toTransition("USER_REJECT"),
true);
The above call to navigate() returns the successor states to the DESIGN
state on a life cycle managed object (<life_cycle_managed>), following
valid USER_REJECT transitions.
Note that the extra series’ were added using the ‘Default’ locale in the
enumCustomize utility. This means that they will only be visible if the browser
language is set to English (US).
<Arg>
<!-- Translation of the word "Basic" must be the same
as
the translation done in commonLifeCycles.xml -->
<?loc-begin key="BASIC_LIFECYCLE_NAME" maxlen="30"
match=
"commonLifeCycles.xml:BASIC_LIFECYCLE_NAME"?>Prototype_
Reject<?loc-end?>
</Arg>
</AttrValue>
Note
If this rule is defined at Site or Organization level, object initialization rules
defined at context level may need to be disabled.
Note
The version now shows rel_A, as defined in the StateBasedVersioning.xml file
in the beginning.
This section contains information on customizations within the Type and Attribute
Management utility.
Background
You want to define complex calculated attributes that cannot be expressed with the
simple OOTB operations available for combining attribute values from a given
object. In some cases, the algorithms may be more complex than the basic
operations. In some cases the calculation may need to traverse relationships to
other objects, often recursively, to accumulate information from a structure. In
some navigation, config spec processing may be involved. In some cases, data
from an external system may be required. You want a simple API for defining and
implementing these custom algorithms, and want to assign the values of those
calculations to an attribute in the Type and Attribute Management utility.
You can implement a BusinessAlgorithm class and easily execute it with a
calculated attribute to see the results of your complex calculations in Windchill
UIs.
Scope/Applicability/Assumptions
BusinessAlgorithm is only for use with calculated attributes.
Solution
Implement a custom BusinessAlgorithm and execute it with a calculated
attribute.
Prerequisite Knowledge
To achieve this result, you need to have an understanding of the following:
• Calculated Attributes — Attribute Customization
@Override
public Object execute(BusinessAlgorithmContext context, Object
[] args) {
// Your complex calculations should go here
return “Hello World: “ + args[0];
}
@Override
public Object getSampleValue() {
// A realistic example value of the same type as the result of
execute
// should be returned here. For this case a string.
return “A Sample Value”;
}
Performance Considerations
Be aware that your business algorithm will be evaluated wherever your calculated
attribute appears in the Windchill UI. For example, if a table has been customized
to display your calculated attribute, the business algorithm needs to be run for
each row in the table. If the algorithm involves database queries or complex
computations it could potentially cause significant performance issues. Therefore
it is highly recommended that your business algorithm be as performant as
possible. Some ideas could include batched database queries, caching results and/
or partial static computations, etc.
You may refer to the sample “sum” algorithm
(AbstractCarambolaAttributeSumBusinessAlgorithm) discussed
below, for an example on a reasonably performant algorithm for summing the
values of an attribute over an entire Part structure. Also, you could refer to the
CarambolaAttributeSumBusinessAlgorithmTestIntegration
test for an example of performance testing this sample business algorithm.
Sample Code
Packaged Samples
AbstractCarambolaAttributeSumBusinessAlgorithm
This is an example business algorithm that calculates and return the numerical
"sum" of the specified attribute on all of the parts in a part structure. This
algorithm is intended to be used in a "Formula" property on a numeric attribute.
The internal name of the attribute to sum is passed in as the first argument to the
algorithm.
Because the technique to add a list of numbers varies based on the data type,
subclasses of this abstract class will actually handle the summing of values of
different data types. We provide 3 subclasses that handle these data-type specific
details:
• IntCarambolaAttributeSumBusinessAlgorithm
• FloatCarambolaAttributeSumBusinessAlgorithm
• FloatWithUnitCarambolaAttributeSumBusinessAlgorithm
These subclasses must override 2 data-type specific methods: one is to provide a
typical sample value of that data type that is used for formula validation
(getSampleValue()), and one is to add up a list of values of this data type
(calculateSumValue()).
So to use this algorithm on a floating point attribute, enter something like the
following expression in the formula property of a calculated attribute in the Type
and Attribute Management utility:
execute("com.ptc.carambola.customization.examples.busi
nessfield.FloatCarambolaAttributeSumBusinessAlgorithm",
"<name of a floating point attribute>")
This example code can be viewed in this location: <Windchill>\
Windchill\srclib\wnc\
Related Information
Related Customization Documentation
• Calculated Attributes — Attribute Customization
This section describes the customization points in the Windchill Options and
Variants capabilities.
Procedure
The
com.ptc.windchill.option.delegate.impl.NullOptionSet
FetcherDelegate delegate is available to restrict a specific object type from
being assigned with an option set. This delegate specifies the object type to
restrict. This can be defined using a service property in Windchill.
<Configuration targetFile="codebase/service.properties">
<!-- OptionSet Fetcher Delegates -->
<Service context="default" name="com.ptc.windchill.
option.delegate.OptionSetFetcherDelegate">
<Option cardinality="duplicate" requestor="null"
selector="WCTYPE|wt.part.WTPart| com.myorg.OrgPart"
serviceClass="com.ptc.windchill.option.delegate.impl.
NullOptionSetFetcherDelegate"/>
</Service>
</Configuration>
3. The following command saves the changes in the file to Windchill services
properties:
xconfmanager -i codebase/com/ptc/windchill/options/
customization/example1.properties.xconf -p
This command causes Windchill to restrict all object of this type for assigning
an option set.
Note
The above is an example to illustrate the steps. The appropriate object type
musts be defined and XCONF file created at the appropriate location.
RegisteredOptionSetLink
Out-of-the box association class that associates an OptionSet to an
OptionSetAssignable object. With this by default option set gets assigned
to an OptionSetAssignable object.
AbstractOptionSetFetcherDelegate
This is an abstract delegate class defined to provide customization capability to UI
and processing. This class has following methods which can be implemented to
customize logic:
• getAssignedOptionSet : This is a abstract method that can be
implemented to determine option set for specified object.
• isAssignOptionSetAllowed : This is a method that specifies if the
custom logic needs the capability of assigning option set to object in user
interface. When this is allowed, the UI can be used to create
RegisteredOptionSetLink association with an object.
Please refer to the Windchill Java Documentation for more information about
method signature and expected input and output parameters.
Procedure
Procedures for extending classes using the Windchill Information Modeler are
defined in the Windchill Customization Guide. For simple extensions of the
default interface implementation use this process:
Note
Do not modify or replace any classes that were provided when Windchill
was installed. These files may be replaced by future software releases.
Example
You have defined a new custom type of part with its own set of business rules.
The requirement for this type or its structure is such that it determines the option
set with some custom logic. This custom logic does not require any direct
association with the part type. Instead it uses some information on a part to
determine option set. It also requires that there is no option set determined. Then
based on information on the part it expects to use out-of-the box behavior to
determine the option set.
After defining a new custom type of part with its own set of business rules, there
is a business requirement for this type, or its structure, to determine the option set
with some custom logic. This custom logic, instead of having a direct association
with the part type, uses some information on a part to determine option set. It also
requires that there is no option set determined. Then based on information on the
part it expects to use out-of-the box behavior to determine the option set.
Note
To enable the auto-suggest capability, set the Allow Choice Auto Suggest
preference to Yes.
Prerequisite Knowledge
To achieve this objective, you must have the understanding of the following:
• Basic development including JSP, JavaScript, Custom taglibs
• Windchill xconfmanager concepts
Procedure
if (bean.getChoice() != null) {
number = bean.getChoice().getNumber();
name = bean.getChoice().getName();
description = bean.getChoice().getDescription();
}
if (bean.getAlias() != null) {
number = bean.getAlias().getNumber();
name = bean.getAlias().getName();
description = bean.getAlias().getDescription();
}
Note
Ensure the addSuggestions method is called from the custom
getFormatedSuggestions method.
3. Register the suggestable class by adding it to the list of services present in the
typedServices.properties. The custom suggestable class must be
registered in an xconf file and then propagated into the /codebase/
service.properties file using xconfmanager.
<Service context="default" name=
"com.ptc.core.components.suggest.Suggestable">
<Option cardinality="duplicate" selector="optionalPicker" requestor=
"null"
serviceClass="<your_Suggestable> " />
</Service>
Other Customizations
For other customizations such as changing the information triggering the search
(for example, typing option.c provides display results for named option and
choices starting with the letter c), or to search or display either soft types or soft
attributes, a custom Suggest class can be created as mentioned in the above
sections, and the constructSuggestions (SuggestParms
suggestParms) method can be overwritten, where the custom logic is added
for changing the searchTerm or fetching and displaying the soft types or soft
attributes.
This topic describes the customization hooks that are available for Product Family
management.
1393
Custom Actions in Variant Specification
Structure
You can extend and add custom actions to the context menu of the part structure in
the variant specification structure. To add the action in the Matrix Editor, add the
following in the context menu of the matrix BOM tree:
<action name="customURLActionGWT" type="psb" />
Implementation Guidelines
1. Variant baseline, variant specification, or both, must be included in the
selected items. If parts are included in the selected items list:
• Use the WhereUse mechanism to search the selected part from the
configurable structure to create path based on the related variant
specification and configurable module (root parent).
Example
: Custom Horizontal Layout Renderer
Note
Characters such as “|” or “.” must be replaced with the supported characters.
You can manage div tags by the rules from the CSS file. See the following
example for displaying cell indicator, object name, and status attributes in the
Matrix Editor.
.pfb-matrix-cell-horizontal { height: 16px; }
pfb-cell-attribute-value {
float: left;
height: 16px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0px 3px;
}
In the above image, the defined width for the Status attribute is 70px. The
attribute value “In Procurement” is longer than the defined width of the cell and
appears truncated with an elipsis (“...”).
Example
To provide this functionality for default horizontal and vertical renderers, add two
CSS rules to the Windchill CSS file.
.pfb-matrix-cell-horizontal > span:empty::before {
content: 'EMPTY VALUE';
.pfb-matrix-cell-vertical:not(.pfb-matrix-cell-empty)
div.x-component:empty::before
{
content: 'EMPTY VALUE';
Note
If you change the default horizontal or vertical renderer, these rules may get
outdated and stop working. After making any changes in the HTML structure,
you must ensure that these rules are still valid.
Solution Elements
Element Type Description
com.ptc.windchil Interface Generalizable interface
l.enterprise.pro for copying a variant
ductfamily.delega specification.
tes.PasteVariant
SpecDelegateIfc
com.ptc.windchil Delegate class Supports the Copy/Paste
l.enterprise.pro of a Variant Specification.
ductfamily.delega
tes.PasteVariant
SpecDelegate
Customization Steps
1. Create a new Java class (delegate) that extends the
PasteVariantSpecDelegate.
Note
The solution for customizing the Location field will follow the same approach
used to customize other attributes within the Matrix Editor.
Create a custom GWT module and compile client side GWT code in the ME
application Create custom GWT attribute renderer to display the attribute
differently than an out-of-the-box renderer. Specify the renderer in the data utility
class (method used is set Rendere ())
Pre-requisite
To apply the customization, you must have the understanding of the following:
• Basic web development using JAVA
• GWT
• Custom tags
• HTML forms
Customization Points
Implementing ExampleGWTLocationCellEditor
The ExampleGWTLocationCellEditor method extends
CustomTreeCellEditor and implements HasWidgets interface. It
provides CustomLocationWidget to LocationField in constructor and
handles specialKeyEvents.
Implementing CustomLocationWidget
CustomLocationWidget extends LocationPasteWidget that already
has six individual fields created and registered all the necessary events for
synchronization of fields. Key methods to override are:
• protected void createPastePanel(): locationPasteField
must be created here and placed in the mainPanel.
• protected void syncFocusFields(): Responsible for
synchronization between the individual fields and locationPasteField.
This method is executed every time there is a synchronization required
between the location input and the individual fields. For example, if you paste
the correct location in the location input field.
• protected void syncLocationPasteField(): Responsible for
synchronization between the locationPasteField and the individual
fields. This method is executed every time there is a synchronization required
between the individual fields and a single location input. For example, if you
modify one of the location fields.
Implementing ExampleGWTLocationCellRenderer
ExampleGWTLocationCellRenderer must extend
CustomCellRenderer<M>. Override the render method to customize.
Implementing ExampleGWTDataUtility
Needs to indicate ExampleGWTLocationCellEditor and
ExampleGWTLocationCellRenderer.
Sample Code
The following is the sample code that you can use to customize the Location
format from %vX%vY%vZ%aX%aY%aZ to %aZ%aY%aZ%vZ%vY%vX.
• refreshPart: This Key is used to provide a list of part OIDs for which the
sub-part structure must be refreshed. The refresh of the part structure reloads
the sub-structure rows and cells and reflects changes to the structure including
new or deleted parts. Any expansion of the child rows will be lost and all the
first level children under the part will be collapsed after the refresh. Multiple
Note
• The replacements are handled first. So if there is a common part in the
result map for the replacement and refresh keys, the updated or new OID
of the part must be provided in the refreshPart or
refreshParentOfPart key.
• If the custom action changes are related to the exclusion or inclusion of a
part or add, remove, or update of the part from the variant baseline, to
reflect these changes, the sub-structure of the parent of this part must be
updated. This can be achieved by providing the part OID as value for key
refreshParentOfPart in the result map.
• If a part is modified by the custom action such that its iteration is changed
(new OID) and this part also had a sub-structure, along with the
replacement map, the iterated part OID must also be added to the
refreshPart key in result map. If the OID of the part changes, the
usage link between the part and the children is also updated. To update the
UI with the new usage links, the sub-structure of the part must be
refreshed.
Sample Code
The following sample code assumes that the status enumeration has the following
key value pairs:
• status1, Status 1
• status2, Status 2
• status3, Status 3
• status4, Status 4
• status5, Status 5
To add any custom JavaScript pages, create a new custom jsfrag file. The
file must be deployed in the codebase\netmarkets\javascript\util\
jsfrags folder. To include the file in all the pages, run the following command:
Windchill/bin>ant -f jsfrag_combine.xml
This will make the js available in the main.js.
For more information, see Adding Custom Code to all Windchill Architecture
Pages.
Sample Code
The following example appends the Modifier Name and Modified Time values of
the part revision to the New Revision column of the Update Baseline Objects UI.
Examples
The StructureModel represents a specific usage of an object (usage link ID,
version ID, and master ID) and can be passed back and forth between the client
and server. All the repeated usages of the same object (with same usage link) are
represented by the same StructureModel. For this reason, you must use the
TreeModel to get the parent object of a specific row in a tree.
This chapter contains details on customizing security labels to providing the set of
security label values for a given custom security label and for determining
authorized participants for each security label value on either a standard or custom
security label.
1437
Customizing Security Labels
There are two types of security labels available in Windchill: custom security
labels and standard security labels. For both standard and custom security labels, a
security label always has a null, or unrestricted, label value and can have one or
more additional label values. These non-null label values can be defined to allow
access only to users who are cleared for that label value. Cleared users are called
authorized participants. Security label values that clear all users can be used as
purely informative markings.
Standard security labels have a pre-defined set of a null and one or more non-null
values established when the standard security label is configured. When applying
a standard security label to an object, a user selects the null or one of these pre-
defined non-null values from a drop-down list. Each object can have only one
value applied for each standard security label configured. If the standard security
label is configured to be multi-valued, then more than one value can be applied.
Custom security labels do not have a pre-defined set of values. When applying a
custom security label to an object, a user enters a value for the custom security
label into a text field or leaves the text field blank to specify the null value. The
set of custom values may be too numerous or complex to pre-define, or may
originate outside of Windchill. You can customize how the custom security label
values are translated between the external display value in the text field and the
internal value stored in Windchill. In addition, you can customize how the
authorized participants are determined for each security label value on either a
custom or standard security label, and how the participants that are allowed to
modify each security label value are determined.
The use of these customizations allows you to link your Windchill system to
another system that may contain user data to determine if a participant is cleared
for a security label value. For example, your company may collaborate with other
companies using a separate non-disclosure agreement (NDA) for each company
interaction. After a user agrees to the NDA, the user is automatically added to a
corresponding Windchill group that represents participants in that NDA. Since
some of the interactions are between multiple companies, a user needs to be a
member of every NDA group involved to have full access to all Windchill data in
the collaborative product.
To set up this scenario to work well with security labels, a custom security label
can be implemented that allows values that can represent multiple NDA groups
rather than the configured list of values offered with standard security labels. You
can also use a custom evaluator to determine if a participant is a member of every
group required to access an object. For example, a collaborative product has been
set up between your company and two others: Company A and Company B. A
user must be a member of both the NDA group for Company A and the NDA
group for Company B to be able to access an object in the collaborative product.
The object in the product has a custom security label applied called Third Party
Proprietary with the value of CompanyA,CompanyB. Custom security label
Note
The security label could have been defined as a standard label with pre-
defined values CompanyA, CompanyB, and CompanyA-CompanyB. However
if your company works with many companies and the list of companies
changes, it may not be practical to pre-define all of the companies and
combinations of NDAs that could apply to a particular object.
The authorized participants for the Third Party Proprietary custom security label
are determined using a custom evaluator class. When a user tries to access an
object with the Third Party Proprietary label applied, the custom evaluator class
searches to find out if the user is a member of the appropriate groups associated
with the security label value applied and then returns either a true or false value to
specify if the user is cleared for the security label and can subsequently access the
object.
The custom evaluator class can also be used to determine which participants are
able to modify the security label values applied to an object. There may be a case
where a user is not familiar with the contract between your company and
Company A, so you do not want that user to modify the Third Party Proprietary
security label settings on an object. You may want to prevent users from changing
the security label value of an object based on the life cycle state of the object. For
example, you could create a custom evaluator that restricts value modification for
objects in the Released state. Using the custom evaluator class on either a custom
or standard security label, you can specify which participants are able to modify a
particular security label’s values.
The following customizations can change how security labels work:
• Including a custom security label in the
securityLabelsConfiguration.xml file.
• Converting between the external and internal custom security label values
using a custom translator class.
• Specifying the participants authorized for the security label value and those
who can modify the security label value using a custom evaluator class.
Note
The custom evaluator class can be used for both standard and custom
security labels.
Information about security labels is available from the Windchill Installation and
Configuration Guide or from the following topics in the Windchill Help Center:
• Specialized Administration ▶ Ensuring Data Security ▶ Security Labels and
Agreements ▶ Security Labels
• Installation and Upgrade ▶ Windchill Installation and Configuration ▶
Configuring Security Labels
Best Practice
If you are using custom security labels, PTC recommends adding validation to
the user interface if users are able to enter values manually, such as by using
the text field provided by default when custom security labels are configured.
A custom translator class is recommended to validate the values to prevent
unexpected values from being stored in the database, either if the user enters
an invalid value in the user interface or if an invalid value is specified in an
import file.
com.ptc.core.foundation.security.server.impl.SACFSecurityLabel
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_
LABEL>.serverFunction.arg1=
PID{<SECURITY_LABEL>}
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL>.longDescription=
<LONG_DESCRIPTION>
where:
• <SECURITY_LABEL> is the custom security label name. This value
should use only alphanumeric characters and the underscore character. The
string
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_
LABEL> is the value that will be specified for the
SecurityLabelResourceKey element for the custom security label
later in this configuration. While there is no requirement for the
<SECURITY_LABEL> value to match the name attribute specified for
the CustomSecurityLabel element in the security labels
configuration file, that is the convention used in this guide.
Note
A security label name is stored as a server-calculated attribute (SCA).
Each SCA must have a unique name. The Logical Attributes Report
provides a list of all current SCAs. You can access this report from
<Windchill>/netmarkets/jsp/lwcType/
logicalAttributesReport.jsp.
Tip
Because custom security label values are not pre-defined, there is no
long description available to display on the information page for the
custom security label. Any information about the custom security label
values can be included in the long description for the custom security
label.
For example, add the following lines to the end of the file for configuring the
example custom security label:
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.
value=
Third Party
Proprietary
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.
dataType=
java.lang.
String
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.
serverFunction=
com.ptc.core.foundation.security.server.impl.
SACFSecurityLabel
WCTYPE|wt.access.SecurityLabeled~SCA|
THIRD_PARTY_PROPRIETARY.serverFunction.arg1=
PID{THIRD_PARTY_
PROPRIETARY}
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.
longDescription=
The "Third Party Proprietary" label indicates the
business
object's level of third party corporate sensitivity.
Note
Additional configuration is required to enable object initialization rules,
agreements, auditing, and subscriptions for custom security labels, but the
steps are the same for standard and custom security labels.
For information about enabling these additional capabilities, see the Security
Labels Configuration Steps in the Windchill Installation and Configuration
Guide or the Windchill Help Center.
Note
If custom evaluation is needed when determining if a participant is restricted
by a security label value, or when determining if a participant is able to
modify a security label value, then a custom Java evaluator class is required.
Handling an AccessControlSurrogate
When Windchill access control service methods are called to evaluate a user's
access rights to information, the methods may be given a persistable object or a
wt.access.AccessControlSurrogate. The
AccessControlSurrogate acts as a stand-in for a persistable object, to
evaluate access rights for the information returned when a database query is
performed requesting specific attributes of an object rather than a full persistable.
The surrogate contains attributes from the class it is representing and includes all
possible attributes necessary for making the access control decision.
The boolean isRestrictedBySecurityLabelValue(WTPrincipal
principal, SecurityLabeled object, String label_name,
String label_value) method defined by the
wt.access.UnrestrictedPrincipalEvaluator class could be given
an AccessControlSurrogate object. If you override this method in a
custom Java evaluator class, your custom code should check if the object is an
instance of AccessControlSurrogate before trying to check various
attributes.
The wt.fc.ObjectIdentifier method getId() can be used to get the
unique identifier of the represented persistable object. The class name in the
ObjectIdentifier is wt.access.AccessControlSurrogate. The
surrogate has a getTargetClassName method which can be used to get the
class name of the represented persistable object. For example:
Class targetClass = Object.class;
if (object instanceof AccessControlSurrogate) {
try {
targetClass = Class.forName(((AccessControlSurrogate)
object).getTargetClassName());
}
catch (ClassNotFoundException cnfe) {
...
Note
An example illustrating the use of a custom security label can be found in the
<Windchill>/conf/securityLabelsConfiguration_
sample.xml file. While the sample configuration file includes sample data
similar to the example configuration used in this document, actual values from
your system are required to successfully configure custom security labels.
A description of the sample configuration is available in the Security Labels
Example Configuration section, found in the Windchill Installation and
Configuration Guide or the Windchill Help Center.
CustomSecurityLabel element
The CustomSecurityLabel element contains the data for defining a custom
security label, the authorized participant for the custom security label values (if
not all users), the agreement type (if any) associated with the custom security label
Best Practice
Keep the name attribute of the CustomSecurityLabel element and the
internal custom label values as short as possible. You can use the
TranslatorClass element to reduce the size of the internal values stored
in the database. For more information, see section Create a Custom Java
Translator Class.
Note
Even if security labels are globally disabled, the security label resource keys
specified in the configuration file must exist in the
accessModelRB.rbinfo for the method server to start.
For more information on disabling security labels, see Disabling Security
Labels and Values in the Windchill Help Center .
Background
Out-of-the-box Windchill Visualization Services can create representations three
ways. They are by manual creation from the Windchill UI, the check-in of a
Representable (an object that can have Representations; i.e. EPMDocument,
WTPart, WTDocument), and by a schedule job. This document will help explain
how to initiate publishing in other ways such as custom code for workflows, from
a custom UI, etc.
This topic also explains how to customize the creation of representations from
such existing mechanisms like the check-in of a Representable or by a schedule
job. Unlike manual creation, there is no out-of-the-box way to specify special
configuration specifications for publishing, or provide business specific
information you may want to capture in the name or description of the
Representation.
Scope/Applicability/Assumptions
Custom publishing should be used when there is a requirement to initiate
publishing in Windchill from a non-standard way (something other than check-in,
manual or schedule), or if you need to modify the input information for a
Representation. Publishing can only be performed on
wt.representation.Representable objects (i.e. EPMDocuments,
WTPart, WTDocuments; including soft and hard typed children).
Intended Outcome
Using the information in this topic will allow end users to perform publishing in a
manner in-line with their business requirement whenever the out-of-the-box
publishing mechanisms are not sufficient.
Solution
Customize publishing by implementing public WVS APIs in custom code and
making WVS aware of this custom code via appropriate WVS property changes.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Java Development
Note
The use of configuration specifications (ConfigSpecs) Additional Resources
on page 1473 includes references to many or all of these subjects.
Solution Elements
Element Type Description
Publisher.class Class file Contains api for doPublish needed for invoking
publishing from code.
Runtime Location: <Windchill>\codebase\com\ptc
\wvs\common\ui
PublisherAction. Class file Used to create the optional actionString to be
class passed to the doPublish method in Publisher. See
JavaDoc for details.
Runtime Location: <Windchill>\codebase\com\ptc
\wvs\common\ui
Visualization Class file Contains helper api’s such as findRepresentable
Helper.class and getRepresentation often needed in custom
code.
Runtime Location: <Windchill>\ codebase\com\ptc
\wvs\common\ui
ScheduleJobs Class file Contains getCurrentContainer method needed
.class when writing custom schedule jobs.
Runtime Location: <Windchill>\codebase\com\ptc
\wvs\server\schedule
wvs.properties Proper- Contains specific properties used with the
ties file Windchill Visualization Service.
Runtime Location: <Windchill>\codebase
Simple Publish
You have an EPMDocument instance with publishable data and you want to create
a default Representation.
String objRef =
ObjectReference.newObjectReference(myepmdoc).toString();
Publisher pub = new Publisher();
boolean result = pub.doPublish(false, true, objRef,
(ConfigSpec)null,
(ConfigSpec)null, true, null, null,
Publisher.EPM, null, 0);
This simple example will simply add a publish job to the publishing queue for
myepmdoc. The resulting default representation named “default” will be published
using the As-Stored or Latest ConfigSpec as defined in wvs.properties (publish.
configspec.default.useasstoredifavailable). Since the forceRepublish parameter
was true, an existing representation with the same name would be replaced.
If you wanted to programmatically provide a name for the representation, or insert
useful business information into the description modify the parameters. For
example:
Publisher pub = new Publisher();
boolean result = pub.doPublish(false, true, objRef,
(ConfigSpec)null,
(ConfigSpec)null, true, “MyRep”,
(ConfigSpec)null, true, “MyRep”,
“My Description”, Publisher.EPM,
null,
0);
Advanced Publish
You have an EPMDocument instance with publishable data and you want to create
a default Representation with your own configuration specification and have the
publish job processed on the high priority publishing queue.
The more advanced features of publishing require using the use of the
PublisherAction class. See the JavaDoc for full details; a couple examples are
shown below.
String objRef =
ObjectReference.newObjectReference(myepmdoc).toString();
PublisherAction pa = new
PublisherAction(PublisherAction.QUEUEPRIORITY, “H”);
ConfigSpec configSpec = <MyHelper.getBaselineConfigSpec()>;
Publisher pub = new Publisher();
boolean result = pub.doPublish(true, true, objRef, configSpec,
null, true,
Note
For WTDocuments, a ConfigSpec is not used and the structureType is
Publisher.NONE.
getRepresentation
In the com.ptc.wvs.common.ui.VisualizationHelper there are also some
convenience methods for getting Representations from a Representable.
public Representation getRepresentation(Persistable d)
As noted previously, the relationship of Representables to Representations is one
to many. However, one of the Representations may be noted as the “default”
Representation. There will be 0 or 1 defaults. The above method will return the
default Representation if one exists. Otherwise, null will be returned.public
Representation getRepresentation(Persistable d, String repName)
public Representation getRepresentation (Persistable d,
String repName)
The method above will return the Representation associated to the Persistable with
the name passed in to the repName argument. If there are no Representations or
one can’t be found with the supplied name, null will be returned.
public QueryResult getRepresentations(Persistable d)
This method will return all of the Representations associated to the Persistable
passed in. If there are no Representations, null will be returned.
All three methods in this subsection require that you have an instance of
VisualizationHelper:
VisualizationHelper vizHelper = new VisualizationHelper();
Representation rep = vizHelper.getRepresentation(d);
while (true) {
while (qr.hasMoreElements()) {
doc = (Representable)((Object[])qr.nextElement())[0];
wtl.add(doc);
}
return wtl;
}
Note
This example contains the use of a BasicPageableQuerySpec and
PagingSessions to avoid out of memory errors. See JavaDoc in the wt.query
and wt.fc packages for details.
This example would effectively ask for all latest iterations of any WTDocuments
found in the current container to be published.
In line six of the example the following method is used from
com.ptc.wvs.server.schedule.ScheduleJobs:
public static WTContainerRef getCurrentContainer()
The result of this method will be null if the schedule job was initiated from the
Exchange container (Site) or if the enableOnContainers value is false in the job
definition (see line four of properties shown prior to the example above). If the
value of enableOnContainers is true, then a WTContainerRef of the container the
schedule job was initiated from will be returned. In the example code, this is used
to filter the scope of the query to the Organization or the Product/Project/Library
container the schedule job was initiated from.
Note
You can have multiple custom schedule jobs. Just use another method name in
the same class, or use a new class altogether. For example:
try {
QuerySpec qs = new QuerySpec(WTDocument.class);
WTContainerRef cr = ScheduleJobs.getCurrentContainer();
if (cr != null) {
ContainerSpec cs = new ContainerSpec();
cs.addSearchContainer(cr);
qs.setAdvancedQueryEnabled(true);
qs.appendWhere(
WTContainerHelper.getWhereContainerIn(cs, WTDocument.
class),
new int[]{0});
}
if (cr != null) qs.appendAnd();
qs.appendWhere(new SearchCondition(WTDocument.class,
Iterated.LATEST_
ITERATION,
SearchCondition.IS_TRUE),
new int[]{0});
while (true) {
while (qr.hasMoreElements()) {
doc = (Representable)((Object[])qr.nextElement())[0];
objRef =
ObjectReference.newObjectReference(doc).toString();
Publisher pub = new Publisher();
pub.doPublish(false, true, objRef, (ConfigSpec)
null,
(ConfigSpec)null, true, "My Rep",
"My Description", Publisher.NONE, null, 0);
}
offset += qr.size();
if (offset >= total) break;
You can use whatever name you want in place of epmFilterMethod. Make sure the
class that contains your custom method is accessible in the Windchill codebase (i.
e. ext.wvs.MyFilterMethods).
The next step is to add the class and method to wvs.properties.xconf. The
following property is empty out-of-the-box. Update it to include your class and
filter method in the format “class/method”.
<Property default="ext.wvs.MyFilterMethods/epmFilterMethod"
name="publish.service.
filterepmdocumentpublishmethod"/>
Once you make the change use the xconfmanager to propagate the changes to
wvs.properties.
Every time a check-in occurs where publishing of an EPMDocument would
normally occur, this method will now be invoked. If the method returns Boolean.
TRUE publishing will be attempted for the specific EPMDocument. If the method
returns Boolean.FALSE, publishing will not be attempted.
The following is a simple example of how to filter out a specific
EPMDocumentType:
public static Boolean epmFilterMethod(EPMDocument epmdoc) {
if (epmdoc.getDocType().equals(
EPMDocumentType.toEPMDocumentType("MANIKIN_
POSTURE"))) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
This is another example where you can filter out the publishing of
EPMDocuments that are in the LifeCycle state of InWork.
public static Boolean epmFilterMethod(EPMDocument epmdoc) {
if (epmdoc.getDocType().equals(
EPMDocumentType.toEPMDocumentType("MANIKIN_
POSTURE"))) {
return Boolean.FALSE;
}
String objRef = ObjectReference.newObjectReference(epmdoc).
toString();
Publisher pub = new Publisher();
pub.doPublish(false, true, objRef, (ConfigSpec)null,
(ConfigSpec)null,
"My Rep", "My Description", Publisher.EPM, null,
0);
return Boolean.FALSE;
}
This is the same example used in Filter Publishing for EPMDocument Check-in
on page 1468 , but notice the use of the doPublish method shown in bold. This
custom job will now create Representations with the name “My Rep” and a
description of “My Description”. Also, note that the returned Boolean from the
method is Boolean.FALSE.
Refer back to Procedure — Invoking Publishing from Custom Code Workflow on
page 1458 for see other useful ways to use the doPublish method.
Note
In the above example the second line states that if the data requested for
publishing is not from the Windchill DB, then just return true. For example if
someone is publishing data on a WTPart that was uploaded from their local
disk, we are saying we don't wish to filter this out and to simply return
Boolean.TRUE.
Limitations
• Customization Boundaries
PTC does not support the customizations of the out-of-the-box CadConvert
classes (a.k.a. Publishers), the Worker Agent, or the WVS Loader. These
components of WVS were not intended for customization and there is no
guarantee that future releases would not break customizations attempted with
these components.
• Custom Schedule Job Performance
Though schedule jobs are run in the background using queues, it is possible to
create very resource intensive queries to return in your custom code. The
examples in the Procedure-Creating Custom Schedule Jobs on page 1463
section showed one technique of using paging to help avoid problems caused
by dealing with large result sets. Be sure your custom schedule jobs are tested
on production-like datasets. What works for cases where the result is 100 does
not always work as well when you have 10’s or 100’s of thousands of results.
• Custom Check-in Filtering Performance
Keep in mind with using the check-in filter techniques shown in Procedure-
Customizing Check-in Base Publishing on page 1467 that your method will be
ran for every Representable that is a candidate for publishing. You method
should be efficient and try to do as little as possible to determine cases where
Additional Resources
• Java Development: http://java.sun.com
• Getting Started with Windchill Visualization Services
• wvs.properties.xconf file in your <Windchill>\codebase directory.
publish.publishqueue.priorities.filtermethod
This method is called when a publish job is being submitted and allows the
priority, queue set and representation name and description to be set.
• [0] = priority H, M L
• [1] = queue set name which should have been configured by
publish.publishqueue.setnames.
• [2] = new name for representation
• [3] = new description for representation
Any of the return strings can be null, in which case the existing value is
unchanged. Controlled by the property
publish.publishqueue.priorities.filtermethod=
com.ptc.wvs.server.publish.PTCWVSPublishFilters/
publishqueueFiltermethod.
publish.publishqueue.usesetworkers.filtermethod
This method will be called when a conversion job is being submitted to the
CADAgent. The representation name and description to be set to return the
worker queue set, and the CADAgent it should use (if this job will be able to use a
worker that has the queueset property that includes the return value). This does
not have to be the same as the actual publishing queue set that is being used. For
example, you could have dedicated worker for assemblies and parts from the same
set.
Controlled by the property
publish.publishqueue.usesetworkers.filtermethod=
com.ptc.wvs.server.publish.MyPublishFilters/
publishUsesetworkersFiltermethod.
Use Case
If there are no workers configured as dedicated workers, the system will pick any
workers which are currently free and job will get published via that worker. The
worker is not a dedicated worker, because no
usesetworkers.filtermethod has been configured.
If you have only dedicated workers and if usesetworkers.filtermethod
has not been defined, the result will be the error: “Error, did not find available
worker of type PROE”.
Sample Code
package com.ptc.wvs.server.publish;
import wt.epm.EPMDocument;
import wt.fc.Persistable;
import wt.fc.QueryResult;
import wt.representation.Representation;
import java.io.File;
import java.util.Properties;
/**
* Example methods for the Dedicated Publisher Queue Set and
Worker
* enhancement
*/
public class PTCWVSPublishFilters
{
/**
* publish.publishqueue.priorities.filtermethod
*
* This method is called when a publish job is being
submitted and
* allows the priority, queue set and
* representation name and descrition to be set
* return [0] = priority H, M L
* [1] = queue set name which should have been
confgured by
* "publish.publishqueue.setnames"
if( epmdoc.getAuthoringApplication().toString().toUpperCase().
equals("PROE") )
{
if(epmdoc.getDocType().toString().equals("CADDRAWING")){
ret[0]="L";
}
if(epmdoc.getDocType().toString().equals("CADCOMPONENT")){
ret[0]="M";
}
if(epmdoc.getDocType().toString().equals("CADASSEMBLY")){
ret[0]="H";
}
if (epmdoc.getDocType().toString().equals("CADDRAWING")) {
ret[1]="PROEDRW";
}
if (epmdoc.getDocType().toString().equals("CADCOMPONENT")) {
ret[1]="PROEPRT";
}
if (epmdoc.getDocType().toString().equals("CADASSEMBLY")) {
ret[1]="PROEASM";
}
ret[2]="SITHIK_PROE_REP";
ret[3]="SITHIK_PROE_DESC";
}
System.out.println("publishqueueFiltermethod outputs:");
System.out.println(" Queue Set: " + ret[1]);
/**
* publish.publishqueue.usesetworkers.filtermethod
*
* This method will be called when a conversion job is being
* submitted to the CADAgent representation name and
description
* to be set return the worker queue set the the
* CADAGent should use, ie this job will be able to use a
* worker that has the "queueset" property that includes the
* return value. There is not reason that this has to be the
* same as the actual publsihing queue set that is being used,
* for example you could have dedicated worker for assemblies
* and parts from the same set.
* Controlled by property
* publish.publishqueue.usesetworkers.filtermethod=
* com.ptc.wvs.server.publish.MyPublishFilters/
* publishUsesetworkersFiltermethod
*
**/
public static String publishUsesetworkersFiltermethod(Persistable
p,
String workerType,
String cadType, String fileName,
String requestQueuePriority,
String requestQueueSet)
{
System.out.println("publishqueueUsesetworkersFiltermethod : "
+ p + " " +
workerType + " " + cadType +
" " + fileName + " " + requestQueuePriority + " " +
requestQueueSet);
ret="PROEPRT";
}
if (epmdoc.getDocType().toString().equals("CADASSEMBLY")) {
ret="PROEASM";
}
}
}
return ret;
}
<Property name="wt.queue.removeCompleted.PublisherQueuePROEDRW1"
overridable="true" targetFile="codebase/wt.properties" value=
"false"/>
<Property name="wt.queue.removeCompleted.PublisherQueuePROEDRW2"
overridable="true" targetFile="codebase/wt.properties" value=
"false"/>
<AddToProperty name="publish.publishqueue.setnames" value=
"PROEDRW"/>
<Property name="publish.publishqueue.usesetworkers.forqueueset.
PROEASM"
overridable="true" targetfile="codebase/WEB-INF/conf/wvs.
properties""
<Property name="wt.queue.removeCompleted.PublisherQueuePROEASM1"
overridable="true" targetFile="codebase/wt.properties" value=
"false"/>
<Property name="wt.queue.removeCompleted.PublisherQueuePROEASM2"
overridable="true" targetFile="codebase/wt.properties" value=
"false"/>
<Property name="publish.publishqueue.usesetworkers.forqueueset.
PROEPRT"
overridable="true" targetfile="codebase/WEB-INF/conf/wvs.
properties""
value="PROE"/>
<Property name="wt.queue.removeCompleted.PublisherQueuePROEPRT1"
overridable="true" targetFile="codebase/wt.properties" value=
"false"/>
<Property name="wt.queue.removeCompleted.PublisherQueuePROEPRT2"
overridable="true" targetFile="codebase/wt.properties" value=
"false"/>
<Property name="publish.publishqueue.priorities.filtermethod"
overridable="true"
targetfile="codebase/WEB-INF/conf/wvs.properties""
value="com.ptc.wvs.server.publish.PTCWVSPublishFilters/
publishqueueFiltermethod"/>
<Property name="publish.publishqueue.usesetworkers.filtermethod"
overridable="true"
targetfile="codebase/WEB-INF/conf/wvs.properties""
value="com.ptc.wvs.server.publish.
PTCWVSPublishFilters/publishUsesetworkersFiltermethod"/>
<Property name="wt.queue.max.processQueues"
overridable="true"
targetFile="codebase/wt.properties" value="60"/>
Background
When an Interference Definition has been submitted for Interference Detection,
the Interference results are returned to WVS to be processed. Based on these
results, WVS will create a new Interference Report and associate new or existing
Interference objects to that report. Each Interference object has Description,
Assignee, State, User Severity, and Name attributes with corresponding out-of-
the-box values of “blank”, “unassigned”, “Open”, “0” and a unique object
identifier. For the State attribute, the default value of “Open” is determined by the
out-of-box lifecycle template and maybe different depending on the lifecycle
template in use. This document will describe how to customize WVS to
automatically set the Description, Assignee and State based on customer business
needs.
Additionally, the first time an Interference Definition is submitted for Interference
Detection, only new Interference objects are created. All subsequent submissions
of the same Interference Definition will result in a new Interference report that
may have existing Interference objects from previous reports. The WVS
Interference processor has the ability to identify if existing Interference objects
already exist and link them to the new Interference report rather than creating new
ones. The processor conforms to a set of rules for determining if an Interference
described in the results returned from the Creo View Client Adapter matches an
Interference object already associated to the current definition. This document
explains how to customize these set of rules for determining equivalency between
Interferences.
Scope/Applicability/Assumptions
Custom Interference Detection should be used if the default values for
Description, Assignee, State, User Severity, and Name for new or existing
Interference objects are not adequate. Also should be used if the out-of-the-box
rules for determining Interference equivalency doesn’t meet requirements.
Intended Outcome
Using this best practice will allow end users to perform Interference Detection in a
manner that addresses their business requirement whenever the out-of-the-box
Interference mechanisms are not sufficient.
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
• Java Development
• WVS Interference Detection concepts such as Interference Definition and
Interference Report.
The Additional Resources section below includes references to many or all of
these subjects.
Solution Elements
Element Type Description
InterferenceDetection- Java file Contains example code
Hooks.java for implementing the
customizations that this
document describes.
Runtime Location:
Windchill/prog_
examples/wvs/com/
ptc/wvs/
InterferenceDetec
tionHooks.java
InterferenceInfo.class Class file Represents all
information regarding a
single Interference
contained in an
Interference Report
generated by the Creo
View Client Adapter.
Used by the WVS
Inteference processor for
creating new Interference
objects or updating
existing ones.
Runtime Location:
<Windchill>/
codebase/com/ptc/
wvs/server/
Customization Points
Custom Method: getInterferenceAttributeValues
Parameter Description
Collection<InterferenceInfo> The WVS Interference processor will
pass in a Collection of all Interference
Information extracted from an
Interference Report generated by the
Creo View Client Adapter.
WTDocument A reference to the Interference
Definition in which the new
Interference Report and Interference
objects will be associated to.
Limitations
The customization for setting Interference attribute values only supports Assignee,
Description,State, User Severity, and Name attributes.
Sample Code
For comprehensive examples, see InterferenceDetectionHooks.java
located in <Windchill>/prog_examples/wvs/com/ptc/wvs.
Configuration Details
Customers must configure the class name and method to use for the filter by
setting the “edrload.partstructurefiltermethod” wvs.property.
The property must be set to a Class/Method. For example, if your class is located
in “ext.custom.partstructure” and the name of the class is
“PartStructureFilter” and the name of the method is
“filterPartStructure”, the following entry should be added to
site.xconf.
• <Property name="edrload.partstructurefiltermethod"
overridable="true" targetFile="codebase/
wvs.properties" value=" ext.custom.partstructure.
PartStructureFilter/filterPartStructure "/>
The modifications will not appear in the Windchill Visualization tab unless the
following property is set to “true”.
• <Property default="false" name=
"edrload.partstructurefilter.enableviztabfilter"/>
Example
Only parts in the released state should be shown in Creo View. Assembly
representations in the release state should include the assembly representation and
exclude the child representations.
/**
* This example filter can be used to include parts in the
"released"
* state and exclude all others. End item parts are added to the
* return map as "NORMAL" and assemblies are added as
* "INCLUDE_REP_AND_EXCLUDE_CHILDREN".
* The result is that only released parts can be viewed.
*
* @param _root - The root node of the structure of the part
being viewed.
* Not used in this example.
* @param _filterPartStructureParentMap - A map of parts to a set
of
* WTPartUsageLink
objects.
* Contains the structure
of the part
* being viewed
* @param _representations - A map of parts to their default
representation.
This chapter describes report generation tools that provide the following
functionality:
• Definition of a broad range of queries against Windchill data using a graphical
interface rather than Java programming.
• Use of these queries to generate reports in several output formats, including
HTML, XML, and CSV.
• Customization of queries and output formats, and re-use of queries and output
formats from other customizations.
• Customization of the Windchill Business Reporting (Cognos) report
presentation, data sources, and other features.
To author new queries using existing report formats, you need only be familiar
with the UML model for the business objects of interest for the query and have an
understanding of the query definition tool. Because the report generation tools
Note
Individual report templates can be imported and exported using the Import and
Export actions available from Report Management. For more information, see
the help available from Report Management.
The following example exports all report template objects in the Windchill PDM
library, the DefaultOrg organization, and site containers that have a name starting
with the characters "monthly":
java wt.query.template.ExportReportTemplate monthly%
"/wt.inf.container.OrgContainer=
DefaultOrg/wt.inf.library.WTLibrary=Windchill PDM"
The following example exports all report template objects in the Windchill PDM
library that have a name starting with the characters "monthly":
java wt.query.template.ExportReportTemplate monthly%
"/wt.inf.container.OrgContainer=
DefaultOrg/wt.inf.library.WTLibrary=Windchill PDM" false
Note
The default configuration file can be overridden by setting the wt.query.qml.
allowedMethodsXMLFile property in wt.properties.
The following attributes are used in specifying the Java methods in the
configuration file:
• class—The package and class containing the method. This attribute is
required.
• name—The name of the method. This attribute is required.
• static—Indicates whether the method is a static method. This attribute is
optional, and if not specified the value is assumed to be false.
The format for specifying a Java method in the configuration file is shown in the
following example:
<methods>
<method class="java.lang.Object" name="toString"/>
<method class="java.lang.Object" name="getClass"/>
<method class="example.HelloWorld" name="example" static="true"/>
</methods>
To add a new Java method, add a new method element to the configuration file,
as shown in the example. Java methods can be removed from the configuration
file, removing them from availability for use in authoring reports, by deleting its
method element.
After adding a new Java method, use the Load Application Data action from the
Query Builder Maintenance Dashboard. This action loads the new Java method and
makes it available for use in the Query Builder. For more information, see Query
Builder Maintenance Dashboard.
Customizing Macros
Customizing macros uses the standard Windchill application services delegation
mechanism. This customization example creates a new macro to automatically
compute a cutoff time.
1. Create a class that implements the MacroExpressionProcessor interface by
performing the following steps:
a. Create a new package or use an existing one. Name the package, for
example, myPackage.
b. Create a new class and inherit from the MacroExpressionProcessor
interface in the wt.query.report package. Name the class, for example,
TimeCutoffMacroProcessor.
c. Compile the class.
d. Fill in the implementation of the buildExpression( ) method. This
implementation reads the current system time in milliseconds, computes
the new time, and creates a new Date. The Date value is returned as a wt.
query.DateExpression. This is necessary because of special handling of
dates in SQL expressions to take into account Java representation of dates
and timezone settings.
public class TimeCutOffMacroProcessor implements
MacroExpressionProcessor {
@Override
@Override
return time;
}
}
e. Fill in the implementation of the getValue( ) method. This value is the
actual Date value as computed in the preceding step. This method is called
to populate Report Builder input fields when a macro is specified as a
default value.
2. Create a logical name for the macro and map it to the implementation class.
For example, for logical name "TIME_CUTOFF" and class "myPackage.
TimeCutoffMacroExpressionProcessor", the entry would be as follows:
wt.services/svc/default/wt.query.report.MacroExpressionProcessor/
TIME_CUTOFF/java.lang.Object/0=myPackage.TimeCutoffMacroProcessor/
singleton
To customize the list of Query Builder types, new entries can be added. For
example, for the class myPackage.myClass, the entry would be as follows:
wt.services/rsc/default/wt.query.report.ClassName/
myPackage.myClass/java.lang.Object/0= myPackage.myClass
Note
This customization is supported for reports using custom input pages.
Several report output formats are provided out-of-the-box. All of these formats are
intended to be general purpose. That is, they should produce reasonable output
from any query. If none of these formats are appropriate, you can modify them or
create completely new formats.
CSS Customization
All of the HTML report formats provided, except those derived from Microsoft
Word, use a CSS1 stylesheet to specify font, color, size, and spacing details. Use
of CSS1 allows these details to be separated from other aspects of page layout and
placed into one or more re-usable stylesheets. Therefore, the easiest way to
customize these aspects of the HTML reports is to edit the CSS files that they use.
For further information about CSS1, refer to the W3C CSS1 specification,
currently available at the following URL: http://www.w3.org/TR/REC-CSS1
Note
If you have difficulty with this URL, try the site URL www.w3.org.
Note
If you have difficulty with this URL, try the site URL www.w3.org.
For additional information about XSLT, refer to the “What is XSLT?” link and the
“Resources” area currently available at the following URL: http://www.xml.com
Note
If you have difficulty with this URL, try the site URL www.xslinfo.com
Stylesheets Provided
One technique for customizing the output format is to modify one of the XSLT
stylesheets that are provided in <Windchill>/codebase/templates/
reports/. These stylesheets are described in detail in the following table.
Note
Within fields that specify an XSLT stylesheet in the Windchill UI, you must
enter file paths that are relative to <Windchill>/codebase/. For
example, excel97WebQuery.xsl must be referenced as "templates/
reports/excel97WebQuery.xsl"
Due to the template-based nature of XSLT, some modifications can be made to the
provided stylesheets based almost solely on a knowledge of the intended output
format (such as HTML). For example, the provided formats that use CSS1
stylesheets generate the references to these files using the following lines in the
XSLT stylesheets:
<link rel="stylesheet" type="text/css"
href="{$windchill}/templates/reports/htmlFormat4Screen.css"
media="screen"/>
The only part of these lines that is not strictly HTML is the portion within the { }
braces which, though similar to JavaScript expression usage, is actually an XSLT
XPath expression. In this case, the expression is referencing the variable
windchill, which was previously assigned the URL of the Windchill codebase.
Note
If you have difficulty with this URL, try the site URL www.xml.com.
Note
If you have difficulty with this URL, try the site URL www.w3.org.
• The encoding listed in the <?xml ...?> header should match that actually used
when saving the file and should be one supported by the XML parser used
(Xerxes 1.2.2). For example, on Windows NT, you can use the Save as
Unicode option in NotePad and specify an encoding of "unicode" in the XML
resource bundle.
Note
The use of Apache Batik, as described in the various chart.xsl stylesheets
(see the table in the section on “Stylesheets Provided” earlier in this
chapter), provides an alternative means of producing SVG with minimal
knowledge of XSLT.
2. Copy static pieces of the sample output to a skeleton XSLT stylesheet, editing
or escaping them as necessary to ensure that they are well-formed XML. (All
XSLT must be well-formed XML.)
3. Author XSLT to transform the input XML into the dynamic portions of the
output, using the sample output as a guide.
The number and complexity of transformations to be done in step 3 can vary
greatly from one format to another and largely determine the effort involved in
creating a new format. XSLT provides extensive capabilities for sorting, filtering,
summing, and combining XML data. Additionally, you can provide XSLT
extension functions and elements that call other languages, including Java and
JavaScript. See the Saxon documentation for further details.
Note
This customization is supported for reports using custom input pages.
The report generation client consists of an HTML form that can prompt the user
for additional report generation input and an HTTP processor that executes the
report and applies the XSL transformations. Both of these clients can be
customized in the same manner as typical HTML client customizations. For
further information, see Customizing HTML Clients Using the Windchill JSP
Framework.
Note
In previous releases, reports that used subtypes (that is, types created using the
Type and Attribute Management utility) needed to be processed using the report
commands (See the com.ptc.core.query.report.command.common package
entry in your installed Windchill Javadoc for more information). The
ReportTemplateHelper APIs now directly support subtypes and customer-
created attributes. While report commands are still supported, they are no
longer required.
Both of the clients mentioned above rely on a wrapper API developed for XSLT
processors. The API can be found in the wt.xml.xslt package entry in your
installed Windchill Javadoc for more information.
This API provides the following functionality:
• Independence from individual XSLT implementations (for example, Saxon,
the XSLT processor library currently in use)
• A high-level abstraction for XML source that hides the details of a particular
implementation (for example, String, Java IO stream, DOM, or SAX)
• A clean API for XSLT operations in Windchill
• Easy-to-use, high-level facilities for complex chaining of XSLT
transformations
For additional capabilities beyond those provided through this API, you can use
the standard JAXP (Java API for XML Processing) APIs, or access Saxon
directly. For further information, see the Saxon Web page, currently available at
the following URL:
http://saxon.sourceforge.net
Note, however, that the XSLT library bundled with Windchill may change in the
future and that users of the Windchill XSLT and JAXP APIs will be affected less
by any such change.
Note
This customization is supported for reports using custom input pages.
Background
Cognos is a third party reporting tool that is integrated with Windchill. It exposes
Windchill Data Source objects in Cognos that can be used in Cognos reports to
retrieve data from Windchill. Cognos is used to format and present the data for
your report.
Scope/Applicability/Assumptions
This documentation assumes that the Windchill Business Reporting (WBR)
solution (i.e. Cognos) has been successfully installed and configured. The
Windchill instance name is referred to as <WindchillInstanceName>. The Cognos
root URL is referred to as <WBRHomeURL>. Typically, if the WBR solution is
installed on <WBRHost>, then the <WBRHomeURL> would be http://<WBRHost
>/Cognos/cgi-bin/cognos.cgi. It is assumed that you can login to <WBRHomeURL
> and you have sufficient Cognos privileges to view Windchill Data Source
objects and create reports.
Assume you will name your new report <MyReport> and it will use the
<MyDataSource> object to retrieve data from Windchill. It is also assumed that
you will be able to create a Report object in Windchill in the Site context.
The WBR solution provides several out-of-the-box Windchill Data Source
objects. If custom Windchill Data Source objects are required for your report, see
ReportTemplate Data Source Customization on page 1535 for more details.
Solution
Use Cognos Report Studio to create a report using a Windchill Data Source.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Cognos Report Authoring
• JMX Console Basic Usage
Procedures
This section contains detailed information about the following customization
procedures:
• Creating a Report.
• Creating a Report in a non-Site context
• Deleting a Report
Creating a Report
1. Login to Cognos using the <WBRHomeURL>.
2. Navigate to “Public Folders > Windchill”.
3. Launch “Report Studio”.
4. Select <MyDataSource> as the Data Source for the report. These appear in the
“Insertable Objects” window under the “Source” tab.
5. Use Cognos Report Studio features to complete the report.
6. Save the report to top level “Public Folders > Windchill” folder as
<MyReport>.
7. Verify the report in Cognos. Refresh the “Public Folders > Windchill” folder
and the <MyReport> object should be listed. Use the “Run with options…”
action to run the report.
8. Expose your report to Windchill. Launch Java Console from installed
Windchill shortcuts. There are two ways to do this:
Deleting a Report
A report that is no longer needed can be removed from the system by deleting
both the Cognos and Windchill Report objects. Assume you want to delete
<MyReport>.
1. Use the Cognos UI to browse to <MyReport> in the “Public Folders >
Windchill” folder (if it is a non-Site context report, then it will be in a sub-
folder) and select the “Delete” action.
2. Then, use the WindchillUI to locate <MyReport> and select the “Delete”
action.
Note
The Reports table supports a multiple row delete action if the Reports table is
within a context and you have delete access rights for Windchill Report
objects in that context.
Limitations
The Cognos report authoring capabilities are designed for many different types of
Data Sources. The WBR integration uses XML Data Sources. These may have
some limitations when compared to other types of Cognos Data Sources. In most
cases, Cognos is able to implement the similar functionality for XML Data
Sources, but there may be implications. For example, it is possible to use
aggregate functions to summarize data, but this processing takes place in the
Cognos server after all data has been received so this may cause performance and
scalability issues.
Cognos Reports have a one-to-one association with the Windchill Report business
object. This object implements the AccessControlled interface so that standard
Windchill access control can be applied. Note that there is no access control
concept of “execution” rights. If a user has “read” access, then that user is also
able to execute the report. The out-of-the-box access control policy for Windchill
Report objects is specified for the Site context which provides Read access for all.
Other access control rules will apply to Report objects based on type inheritance.
For example, the Report object extends WTObject so at the Site level, Full access
is granted for Administrators.
Note
The FloatingPointWithUnits attribute value type is not supported by
Cognos. For more information, refer to article CS000308408.
Sample Code
Examples of Usage in Windchill Code:
Windchill supports out-of-the-box reports for both the Windchill ProjectLink and
Windchill PDMLink solutions. See the Basic Administration section in the
Windchill Help Center for details. Directly modifying the associated objects is not
supported.
Related Websites
• http://www.ibm.com/cognos/support
Background
The Windchill Business Reporting (WBR) solution uses Data Source objects to
retrieve data from Windchill. One type of Data Source is an Info*Engine task. An
Info*Engine task is a text-based document that uses programmatic constructs to
retrieve and manipulate Windchill data. The task must return its data in a tabular
format (i.e. each element must have the same number of attributes) and task must
be commented with special tags and syntax to define it as a WBR Data Source.
Scope/Applicability/Assumptions
This documentation assumes that the Windchill Business Reporting (WBR)
solution (i.e. Cognos) has been successfully installed and configured. The
Windchill instance name is referred to as <WindchillInstanceName>. The Cognos
root URL is referred to as <WBRHomeURL>. Typically, if the WBR solution is
installed on <WBRHost>, then the <WBRHomeURL> would be http://<WBRHost
>/cognos8/cgi-bin/cognos.cgi. It is assumed that you can login to
<WBRHomeURL> and you have sufficient Cognos privileges to view Windchill
Data Source objects and create reports.
Assume you have access to the Windchill server tasks directory, <WindchillHome
>/tasks, to create an Info*Engine task <MyTask> in sub-directory
<MyTaskPackage>.
For WBR integration, you must also have access rights to update the reporting
meta model.
This document does not contain details on how to construct Info*Engine tasks.
See the section Info*Engine User’s Guide on page for this information.
Intended Outcome
The end result of this solution is the creation of your Data Source that can be used
to author Cognos reports.
Solution
Construct an Info*Engine Task Data Source.
where <type> is the parameter Java type, <name> is the parameter name, and
<description> describes the parameter. The following are the allowed
parameter types:
• java.lang.Boolean
• java.lang.Long
• java.lang.String
• java.sql.Timestamp
• java.util.Date
• java.lang.Double
• java.math.BigDecimal
4. Add WBR Data Source column information to the “return” task comment. The
column information must be specified in the correct format for this task to be
considered a Data Source. The syntax for the column comment is as follows:
@return <type> ${<variableName>} {columns: <columnList>}
typeId=com.ptc.windchill.enterprise.report.ReportTask
-->
Customization Points
Sample Code
Packaged Samples
A demo Info*Engine task Data Source, ContextItems, is available in the
“Windchill > Report Tasks > com.ptc.windchill.enterprise.report.ReportTask”
level of the Source tab. The task source is located in <WindchillHome>/tasks/com/
ptc/windchill/enterprise/reports/ContextItems.xml. It retrieves the union of all
Parts and Documents in a specified context.
Additional Resources
Background
The Windchill Business Reporting (WBR) solution uses Windchill and Cognos
objects in the system. Often times these objects are developed in another system
such as a development system and then moved to another system where they are
used in production. This document describes how these Reporting objects are
loaded into a system.
For Windchill business objects, the standard Windchill Data Loading mechanism
is used. These tools are based on describing objects and their attributes in XML
files. The loading is accomplished by instantiating the business objects, populating
the attributes specified in the XML files, and using standard Windchill create
APIs.
For Cognos report objects, standard Cognos SOAP APIs are used. Cognos report
attributes are specified in a Java properties file and the report’s definition is
specified in an associated XML file. These files are processed and the data is
passed to a Cognos SOAP API for creating reports.
Scope/Applicability/Assumptions
This documentation assumes that the Windchill Business Reporting (WBR)
solution (i.e. Cognos) has been successfully installed and configured. The
Windchill instance name is referred to as <WindchillInstanceName>. The Cognos
root URL is referred to as <WBRHomeURL>. Typically, if the WBR solution is
installed on <WBRHost>, then the <WBRHomeURL> would be http://<WBRHost
>/Cognos/cgi-bin/cognos.cgi. It is assumed that you can login to <WBRHomeURL
> and you have sufficient Cognos privileges to view Windchill Data Source
objects and create reports.
Assume you have access to the Windchill server tasks directory, <WindchillHome
>/tasks, to create an Info*Engine task <MyTask> in its associated sub-directory
<MyTaskPackage>. Assume that this task has already been developed and tested
on another source system, <WindchillSourceHome>.
Assume you have access to the Windchill UI and the ReportTemplate,
<MyReportTemplate> in the Site context of another source system,
<WindchillSourceHome>.
Solution
Construct and execute load files for Reporting objects.
Customization Points
Limitations
For Cognos Report loading, there are load file directories that are used for
Windchill out-of-the-box reports. These directories should not be used for custom
load files. The reserved directories are <WindchillHome>/loadFiles/cognosReports
and <WindchillHome>/loadFiles/cognosReports/<assemblyId> where <assemblyId
> is a standard Windchill assembly ID such as wnc, pdml, pjl, etc.
Sample Code
Packaged Samples
A demo load file for Windchill ReportTemplate and Report objects is available in
<WindchillHome>/loadXMLFiles/DemoReports.xml.
Additional Resources
• Reporting Info*Engine Task Data Source Customization on page 1524
• ReportTemplate Data Source Customization on page 1535
• Cognos Presentation Customization on page 1518
Related Websites
• http://www.ibm.com/cognos/support
Background
The Windchill Business Reporting (WBR) solution uses Data Source objects to
retrieve data from Windchill . One type of Data Source is a ReportTemplate. A
ReportTemplate is a standard, persistent Windchill business object that is
maintained via the Report Management utility. It launches the Query Builder to
create and edit a query that is stored as part of the ReportTemplate. When the
ReportTemplate query is executed, standard Windchill APIs are used that apply all
Windchill business logic (e.g. calling Windchill object methods, applying access
control, etc.). Once a new ReportTemplate object is created it can be referenced
from a Report object or exposed and used in the WBR solution as a custom Data
Source.
Scope/Applicability/Assumptions
This documentation assumes that the Windchill Business Reporting (WBR)
solution (i.e. Cognos) has been successfully installed and configured. The
Windchill instance name is referred to as <WindchillInstanceName>. The Cognos
root URL is referred to as <WBRHomeURL>. Typically, if the WBR solution is
installed on <WBRHost>, then the <WBRHomeURL> would be http://<WBRHost
>/cognos8/cgi-bin/cognos.cgi. It is assumed that you can login to
<WBRHomeURL> and you have sufficient Cognos privileges to view Windchill
Data Source objects and create reports.
Assume you have access rights to create a ReportTemplate business object
<MyReportTemplate> in the Site context.
For WBR integration, you must also have access rights to update the reporting
meta model.
This document does not contain details on how to construct ReportTemplate
queries. See the Query Builder online tutorial and help for this information.
Intended Outcome
The end result of this solution is the creation of your Data Source that can be used
to author Cognos reports.
Solution
Use Report Management and Query Builder to construct a ReportTemplate Data
Source.
Solution Elements
Element Type Description
<MyReportTemplate> Windchill Object The Windchill object that
Windchill specifies a query for
ReportTemplate retrieving Windchill data.
Limitations
None.
Sample Code
Packaged Samples
A demo ReportTemplate Data Source object, PartList, is available. It can be
loaded using the following command:
wt.load.LoadFromFile -d
<WindchillHome>/loadXMLFiles/DemoReports.xml -CONT_PATH /
Related Websites
• http://www.ibm.com/cognos/support
Background
The Windchill Business Reporting (WBR) solution supports reports with
parameters. Both Windchill and Cognos viewers provide a basic input page that is
presented to users to gather parameter values when the report is executed. Often
times this input page requires customization for a better end user experience.
There are two basic approaches for customizing input pages, use a standard
Windchill Java Server Page (JSP) or use Cognos report functionality. The
Windchill JSP approach can be used from the Windchill or Cognos viewers. The
Cognos approach can only be used with the Cognos viewer.
Scope/Applicability/Assumptions
This documentation assumes that the Windchill Business Reporting (WBR)
solution (i.e. Cognos) has been successfully installed and configured. The
Windchill instance name is referred to as <WindchillInstanceName>. The Cognos
root URL is referred to as <WBRHomeURL>. Typically, if the WBR solution is
installed on <WBRHost>, then the <WBRHomeURL> would be http://
<WBRHost>/Cognos/cgi-bin/cognos.cgi. It is assumed that you can login to
<WBRHomeURL> and you have sufficient Cognos privileges to view Windchill
Data Source objects and create reports.
Assume you have access to the Windchill server JSP directory,
<WindchillHome>/codebase/wtcore/jsp, to create the JSP input page
<MyInputPage> in its associated sub-directory <MyInputPagePackage>.
Assume you have access rights to edit an existing Windchill Report object,
<MyReport> in the Site context.
Solution
Construct and specify a custom input page for reports.
Customization Points
Cognos reports that use Windchill Data Sources require every parameter value to
be specified. However, a report can be more useful, if the user can optionally
leave parameter values unspecified and the report ignores the related criteria or
implicitly uses a suitable default. To achieve this behavior, it is possible to pass a
parameter value consisting of a single space (“ “) and by making a single space
the default value for the parameter in you input page, the user will not be required
Data Source
Also data source parameters can be excluded using the usual "parametersToOmit"
request attribute. Note, this is a servlet request object attribute list not a parameter
list. it was chosen for simplicity and ease of use.
Limitations
None.
Related Websites
• http://www.ibm.com/cognos/support
Background
The Windchill Business Reporting (WBR) solution uses Windchill and Cognos
objects. There are both Data Source and Report objects that contain text that can
be localized. Localizing the text in these objects allows the text to be displayed in
the client's locale.
Scope/Applicability/Assumptions
This documentation assumes that the Windchill Business Reporting (WBR)
solution (that is, Cognos) has been successfully installed and configured. The
Windchill instance name is referred to as <WindchillInstanceName>. The Cognos
root URL is referred to as <WBRHomeURL>. Typically, if the WBR solution is
installed on <WBRHost>, then the <WBRHomeURL> would be http://
<WBRHost>/cognos8/cgi-bin/cognos.cgi. It is assumed that you can login to
<WBRHomeURL> and you have sufficient Cognos privileges to view Windchill
Data Source objects and create reports.
• Assume you have access to create files in the source directory associated with
<MyPackage> in <WindchillHome>.
• Assume you have created an Info*Engine task <MyTask> in its associated
sub-directory <MyTaskPackage> in <WindchillHome>.
• Assume you have created the ReportTemplate, <MyReportTemplate> in the
Site context of <WindchillHome>.
• Assume you have created a Windchill Report object, <MyReport> in the Site
context.
• Assume you have created a Cognos Report, <MyCognosReport> in the
Windchill folder.
For WBR integration, you must also have access rights to update the reporting
meta model. This document describes procedures for using standard Java resource
bundles to externalize text used in the WBR system. To support localized text, a
language specific resource bundle must be created and the text translated to the
appropriate language. It is assumed that you require support for more than one
language and you have the ability to translate text to your supported languages.
The text elements that are referred to in this document consist of report names,
parameters, and columns. The actual data displayed in WBR reports is returned
from Data Sources. Localizing this data is not covered in this document.
Solution
External localized text to Java resource bundles that can be translated to support a
specific client locale.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Info*Engine User's Guide
• JConsole User Interface
• Cognos User Interface
• Report Management User Interface
Solution Elements
Element Type Description
<MyTask> Info*Engine Task The Info*Engine task for
retrieving and
manipulating Windchill
data.
<MyTaskResource> Resource Bundle Info The resource bundle info
Properties File file used to localize
Info*Engine task text
items.
<MyReportTemplate>- Windchill Object The Windchill object that
WindchillReportTemplate specifies a query for
retrieving Windchill data.
<MyReportTemplateRe- Resource Bundle Info The resource bundle info
source> Properties File file used to localize
ReportTemplate text
items.
<MyReport>Windchill- Windchill Object The Windchill object that
Report is displayed to end users
in the Windchill User
Interface. It acts as a
proxy to a corresponding
Cognos Report object.
<MyReportResource> Resource Bundle Info The resource bundle info
Properties File file used to localize
Report text items.
Customization Points
Limitations
To localize a Cognos report, the Report Studio locale must be set to "en_ZW"
before authoring a report. Cognos reports reference localized data source and
column names based on the Report Studio locale. Any change to these data source
and column names for this locale will result in not being able to look up the
translated text in another locale. The official workaround recommended by
Cognos is to use non-volatile names in a special locale. This special locale is "en_
ZW".
Sample Code
Related Websites
• http://support.congos.com/support
Customization Steps
1. Create resource bundle Java file. For example:
a. Create a <Windchill>\src\com\customReports\psb\
directory and create a file named psbCustomActionsRB.java (see
example source code below).
b. In a Windchill shell, go to <Windchill>\src directory and compile
the java file (replace <Windchill> as appropriate):
javac -cp <Windchill>\codebase;<Windchill>\
codebase\WEB-INF\lib\*;<Windchill>\lib\* com\
customReports\psb\psbActionsRB.java -d <Windchill>\
codebase
For example:
javac -cp C:\ptc\Windchill\codebase;C:\ptc\
Windchill\codebase\WEB-INF\lib\*;C:\ptc\Windchill\
lib\* com\customReports\psb\psbActionsRB.java -d
C:\ptc\Windchill\codebase
This will compile the RB info file to the <Windchill>\codebase\
com\customReports\psb directory.
2. Add action definition entries to <Windchill>\codebase\config\
actions\custom-actions.xml (see example source code below).
a. The url parameter for each action must be changed to point to the custom
report url.
Note
Sample code for custom reports 02 through 25 removed for readability.
package com.customReports.psb;
import wt.util.resource.RBComment;
import wt.util.resource.RBEntry;
import wt.util.resource.RBPseudo;
import wt.util.resource.RBUUID;
import wt.util.resource.WTListResourceBundle;
@RBUUID("com.customReports.psb.psbCustomActionsRB")
public final class psbCustomActionsRB extends WTListResourceBundle
{
/********
* Custom Report 01
*/
@RBEntry("Custom Report 01 Description")
// this is what is displayed in the menu
public static final String PSB_CUSTOMREPORTGWT01_DESCRIPTION
@RBEntry("height=900,width=1000")
// specifies the size in pixels of the report window
@RBPseudo(false)
@RBComment("DO NOT TRANSLATE")
public static final String PSB_CUSTOMREPORTGWT01_MOREURLINFO
= "psb.psbCustomReportGWT01.moreurlinfo";
@RBEntry("report_view.png")
// the name of the icon file, as found in <Windchill>/netmarkets/
images
@RBPseudo(false)
@RBComment("DO NOT TRANSLATE")
public static final String PSB_CUSTOMREPORTGWT01_ICON
= "psb.psbCustomReportGWT01.icon";
} // end class
package com.customReports.psb;
import wt.util.resource.RBComment;
import wt.util.resource.RBEntry;
import wt.util.resource.RBPseudo;
import wt.util.resource.RBUUID;
import wt.util.resource.WTListResourceBundle;
@RBUUID("com.customReports.psb.psbCustomActionsRB")
public final class psbCustomActionsRB extends WTListResourceBundle
{
/********
* Custom Report 01
*/
@RBEntry("Custom Report 01 Description")
@RBEntry("height=900,width=1000")
// specifies the size in pixels of the report window
@RBPseudo(false)
@RBComment("DO NOT TRANSLATE")
public static final String PSB_CUSTOMREPORTGWT01_MOREURLINFO
= "psb.psbCustomReportGWT01.moreurlinfo";
@RBEntry("report_view.png")
// the name of the icon file, as found in <Windchill>/netmarkets/
images
@RBPseudo(false)
@RBComment("DO NOT TRANSLATE")
public static final String PSB_CUSTOMREPORTGWT01_ICON
= "psb.psbCustomReportGWT01.icon";
} // end class
Note
Sample code for custom reports 02 through 25 removed for readability.
<listofactions>
</objecttype>
</listofactions>
Note
Uncomment the number of custom reports needed in the section of code with
the psbCustomReportGWT action names.
<model name="psbRelatedPartsTreeToolBar">
<action name="editingGroupGWT" type="psb" />
<action name="insertExistingPartStructureGWT" type="psb" />
<action name="removeGWT" type="psb" />
<action name="insertNewPartStructureSplitGWT" type="psb" />
<action name="insertNewPartStructureGWT" type="psb" />
<action name="insertMultiNewPartStructureGWT" type="psb" />
<action name="editSplitGWT" type="psb" />
<action name="editGWT" type="psb" />
<action name="editUsageLinkTreeGWT" type="psb" />
<action name="editCommonAttrsGWT" type="psb" />
<action name="separator" type="separator" />
</actionmodels>
Note
Jasper Studio can be configured as an Eclipse IDE plug-in.
5. In the Design panel, from the Basic Elements palette, drag a Table element to
the details area of the Design edotor.
7. On the Dataset wizard, you have option to create dataset from given source,
Select Create new dataset from a connection or Data Source and specify the
dataset name. Click Next.
13. Now on the Data Source Wizard, you should see the newly created adapter as
the default selection. Click Next.
14. On the Fields Wizard, select and move all or relevant fields of Report Template
from Dataset Fields to Fields section, and click Finish.
Browse to Dataset and Query Dialog, replace the Language from sql to csv.
Click OK.
21. On the Jasper Studio window, click Save. To view a preview of the report,
click Preview.
10. Use reportservlet url to construct the URL for executing Report Task.
11. Part of report servlet URL is unique for all Report Task execution. Append
this part to report task name and its parameters.
14. Create fields for Table. Created fields should have name and data-type same as
that of XML output meta-data.
16. Execute the report. Values for Input Parameters must be provided as
configured in the previous steps.
17. For deploying and executing the report in Windchill, perform the steps for
Authoring Jasper reports using Report Templates on page 1563.
Where,
○ WRS_URL and USERNAME are the parameters, which can be created in
Jasper Studio.
○ /ProdMgmt/Parts can be changed depending on required WRS
module.
• selectExpression—A string representing the selected expression.
The selected expression is optional. You may provide any selected filter as
the second parameter to the method getJsonDataSource.
9. Create fields for Table.
10. Drag these fields to the table.
11. Generate the report.
2. If any input page is specified, then that jsp is presented on clicking the report
object.
Prerequisite
Report loader should have an additional field named csvCriteriaPage to
include path of custom criteriaPage JSP. This JSP can be HTML, JS, Core-UI or
Ext JS-based JSP. Report loader file should be similar to input JSP authored for
those reports.
1. To use a reusable component, import the following tags and add to the input
JSP where you want the button to be displayed:
• <%@taglib uri="http://www.ptc.com/windchill/
taglib/saveCriteria" prefix="r"%>
• <r:saveCriteria savedReportName=
"SampleReportCriteria" prefix="r"%></
r:saveCriteria>
2. When you click Save, all input values from mainform (name-value) pair are
considered as criteria for the saved report and the saved report is created. If the
reportViewPort tag is used, then all input fields in the tag are considered
as criteria. If the Input JSP does not include the reportViewPort tag, then
HTML form name should be the same as mainform.
3. If you are required to author input JSP without the reportViewPort tag,
then add all inputs in mainform.
4. To re-define or view the criteria, author a new JSP, and include the JSP in
loader (criteriaPage).
5. API is provided to fetch criteria based on SaveReportOid. Save Report oid
is available in your request parameters.
Request parameter example: String criteriaObjectOid=
request.getParameter("saveReportOROid"); HashMap
inputParams=
SaveReportHelper.getReportCriteria(criteriaObjec
tOid);
Note
For this example, sample Jasper Reports are created in Jasper Studio. This
reports refers to Windchill ReportTemplate (QML) for data sets and its files
are located under JasperIntegration/src_example directory.
For example,
windchill com.ptc.wbr.jasper.util.JRXMLCompiler $WT_HOME/
codebase/JasperReports/Sample/Demo3DBarChart.jrxml
Note
Before proceeding to the next step ensure that the method server is running
in the background.
Note
Restart of method server is not required after loading of Jasper Report.
Note
• Charts shown below are for illustration purpose only. Actual charts may vary
depending on your data sets.
• Accuracy of charts can be improved using correct and comprehensive data
sets.
• Candlestick, Gantt and Open-High-Low-Close charts are also supported.
However, they are not shown in the table below due to unavailability of
matching data sets (for example, Share market and Project management data
sets). You can create relevant data sets to view these types of charts.
References
Jasper Studio Ultimate Guide .This is a third party guide and might change as per
the third party decision.
Following is the list of widgets supported and qualified by PTC.
• Tables
• List
• Nested Tables
• Frame
• Rectangle
• Images
• Static Text
Note
Charts are not supported for Jasper reports in Windchill 12.0.2.0.
1599
Package Type-Based Properties
Package type-based properties are a new feature in the Windchill 10.0 release that
allows customization properties to be assigned to Package objects by class type or
subtype. These properties differ from those typically set in wt.properties,
and from preferences set in the Preference Manager, in that different types of
Package objects may have different settings for the same property. For example,
the EnableContentControl property may be set to “false” for Package types
while simultaneously being set to “true” for TechnicalDataPackage types.
Package type-based properties are intended only for site-level and organization-
level customization, and can only be changed by the Windchill site administrator.
<WPTypePropertySet name="Default">
<WPTypeProperties typeId="com.ptc.windchill.wp.WorkPackage">
<EnableContentControl>false</EnableContentControl>
<CollectorId>CreateWPBaseline</CollectorId>
<IncludedManifestOptions>
<ManifestOption default="true">Interactive</
ManifestOption>
</IncludedManifestOptions>
<IncludedDeliveryOptions>
<DeliveryOption>Full</DeliveryOption>
<DeliveryOption>Incremental</DeliveryOption>
</IncludedDeliveryOptions>
</WPTypeProperties>
<WPTypeProperties typeId="com.ptc.windchill.wp.tdp.
TechnicalDataPackage">
.
. </WPTypeProperties>
</WPTypePropertySet>
Note
The loader prompts for the site administrator user-id and password to perform
this operation.
For convenience, the loader can be used to create an XML file that describes the
current type-based property sets in the system or to recreate the default property
set from the initial install. The newly created XML file can then be modified and
loaded as described above.
To retrieve the currently loaded sets, execute the loader from a Windchill shell
while the Method Server is running as:
java com.ptc.windchill.wp.WPTypeBasedPropertiesLoader
-read <XML file>
To retrieve the OOTB default set from the initial installation, execute the loader
from a Windchill shell while the Method Server is running as:
java com.ptc.windchill.wp.WPTypeBasedPropertiesLoader
-read <XML file> -default
If different property values are required for a sub-type or soft-type, then additional
<WPTypeProperties> elements can be added. For example, the following
defines one set of property values for packages of type
com.ptc.windchill.wp.WorkPackage, and a different set of property
values for the soft-type com.ptc.windchill.wp.WorkPackage|com.MyCompany.
MyPackage.
<WPTypeBasedProperties ...>
<WPTypePropertySet name="My Customized Set">
< WPTypeProperties typeId="com.ptc.windchill.wp.WorkPackage">
:
(Type-based properties for com.ptc.windchill.wp.WorkPackage)
:
</WPTypeProperties>
<WPTypeProperties typeId=
"com.ptc.windchill.wp.WorkPackage|com.MyCompany.MyPackage">
:
(Properties for com.ptc.windchill.wp.WorkPackage|com.MyCompany.MyPackage)
:
</WPTypeProperties>
</WPTypePropertySet>
</WPTypeBasedProperties>
The actual property value used for any specific package type is taken from the
most specific type defined in the XML file. If the exact package type cannot be
found in the XML file, then the file is re-examined for a parent type. This process
continues up the type hierarchy until either an exact type match is found, or the
root package type com.ptc.windchill.wp.AbstractWorkPackage is
reached. If the root type is reached, then the system default property values are
EnableContentControl
The EnableContentControl property is used to enable or disable content
control processing. For more information, see . See the File Table topic in the
Windchill Help Center for more information.
The following tag enables content control processing for this package type:
<EnableContentControl>true</EnableContentControl>
CollectorId
The CollectorId property controls which collection component instance to
use when the “Configure…” link is selected from the “Add to Package” window.
For example:
<CollectorId>MyCustomCollectorId</CollectorId>
ExcludedSeedTypes
The ExcludedSeedTypes property controls object types that cannot be added
as seeds to a package. Object types specified in this property cannot be pasted into
the “Initially Selected Objects” table in the “Add to Package” window. They are
not returned in the “Search Results” table when searching for initially selected
objects.
For example, the following excludes objects of type WTDocument and part soft-
type com.MyCompany.MyCustomPart from being added to the “Initially
Selected Objects” table.
<ExcludedSeedTypes>
<SeedType>wt.part.WTPart|com.MyCompany.MyCustomPart</SeedType>
<SeedType>wt.doc.WTDocument</SeedType>
</ExcludedSeedTypes>
Default value: none – no object types are excluded and the full range of package
seed types is available
IncludedDeliveryOptions
The IncludedDeliveryOptions property controls which delivery options
are presented in the “Zip Package for Delivery” window. The valid delivery
options are:
• Full – displays option “Provide complete delivery”. If selected, an exported
zip file contains all the package contents that are accessible to the recipient.
• Incremental – displays option “Provide incremental delivery from”. If
selected, an exported zip file contains only the package contents that are
accessible to the recipient, and were not included in the base delivery.
• Incremental manifest – displays option “Provide complete delivery with
incremental information from”. If selected, an exported zip file contains all the
package contents that are accessible to the recipient, similar to the “Full”
option, but also contains a manifest file describing incremental changes
between the base delivery and the new delivery.
Regardless of the options specified, all exported zip files for the first version of a
package uses the “Full” option, and the “Zip Package for Delivery” window does
not display the delivery options.
Also, regardless of the options specified, all exported zip files for any version of a
package uses the “Full” option if this is the first version delivered to a recipient.
If either of the incremental delivery options are selected in the “Zip Package for
Delivery” window, then a base delivery must also be specified. Only earlier
deliveries to the same recipient may be used as a base delivery.
Default values: Full, Incremental
IncludedManifestOptions
The IncludedManifestOptions property controls which manifest options
are presented in the “Zip Package for Delivery” window. The valid manifest
options are:
• Interactive – displays option “Include offline viewer”. If selected, an exported
zip file contains an offline view of the package and its contents, but does not
contain a manifest file.
• Static – displays option “Include manifest file”. If selected, an exported zip
file contains a manifest file and the content files associated with the package
object and its members. It does not contain an offline view. The manifest is
also associated to the Delivery object as a primary content file. The name of
the manifest file can be controlled using the ManifestFileName property
(see the ManifestFileName section for more information).
• None – displays option “Do not include any manifest”. If selected, an exported
zip file contains the content files associated with a package object and its
members. It does not contain an offline view or a manifest file.
For example, the following causes all three manifest options to be displayed, and
the “Static” option is pre-selected by default.
<IncludedManifestOptions>
<ManifestOption>Interactive</ManifestOption>
<ManifestOption default="true">Static</ManifestOption>
<ManifestOption>None</ManifestOption>
</IncludedManifestOptions>
StaticManifestClassOverride
The StaticManifestClassOverride property is used to override the
OOTB Java class used to create a static manifest for an exported zip file (see the
IncludeManifestOptions section for more information). The content and
format of a static manifest file can be customized by creating a new Java class and
setting this property to its fully qualified class name.
A custom Java class for creating a static manifest file has the form:
package com.MyCompany
import java.io.InputStream;
import com.ptc.netmarkets.wp.ixb;
import wt.util.WTException;
For example, the following would specify that custom Java class
com.MyCompany.MyStaticManifest be used to create a static manifest
file:
<StaticManifestClassOverride>
com.MyCompany.MyStaticManifest
</StaticManifestClassOverride>
ExcludedMemberContentRoles
The ExcludedMemberContentRoles property controls which types of
content files associated with package members are excluded from an export file.
Also, when Content Control is enabled (see the EnableContentControl
section for more information) content files for these roles are excluded from
RetainCollectionResults
The RetainCollectionResults property controls retention of extended
collection information when creating a new package or modifying an existing
package using the “Add to Package”, “Refresh”, “Save As” (with refresh) and
“Revise” (with refresh) actions. Retaining extended collection information enables
advanced package editing features, such as the “Edit Filters” action.
For example, the following tag enables retention of extended collection
information:
<RetainCollectionResults>true</RetainCollectionResults>
IncludedDeliveryFormatOptions
The IncludedDeliveryFormatOptions property controls which format
options are presented in the Zip Package for Delivery window.
The valid format options are:
• Non_Importable: Displays the Export Only option. If selected, an exported
zip file only contains an offline view of the package and its contents, and
cannot be imported.
• Windchill_Importable: Displays the Windchill Importable option. If
selected, the exported file is required to be a complete delivery (that is, options
for incremental delivery are disabled), and the exported zip file contains data
allowing it to be imported into another Windchill system.
For example, the following causes the Export Only and Windchill Importable
options to be displayed, with Export Only pre-selected by default.
<IncludedDeliveryFormatOptions>
<DeliveryFormat default="true">Non_Importable</DeliveryFormat>
<DeliveryFormat>Windchill_Importable</DeliveryFormat>
</IncludedDeliveryFormatOptions>
ExportOnlyContentFileNaming
The ExportOnlyContentFileNaming property controls which content file
renaming scheme is used to eliminate duplicates in an export file. The valid file
renaming options are:
• AppendSequenceID: Appends sequence identifiers to content file names to
eliminate duplicates (for example, “MyContentFile[2].txt”). Content
files are only renamed when duplicates exist. This function is similar to the
renaming scheme used in prior Windchill releases, and does not guarantee
consistent content file names between two or more separate exports.
• PrependIdentity: Prepends the business object identity to content file
names to eliminate duplicates using the following forms:
○ When Display > Expose Organization is set to True, ObjectType -
ObjectNumber, ObjectName, OrganizationID,
Revision.Iteration - Filename (for example, “Document –
000000001, doc_ex, 12345, A.1 - MyContentFile.txt,” where “12345”
identifies the Organization Name, CAGE Code, DUNS Number, or ISO
6523 for the organization).
○ When Display > Expose Organization is set to False, ObjectType -
ObjectNumber, ObjectName, Revision.Iteration -
Filename (for example, “Document – 000000001, doc_ex, A.1 -
MyContentFile.txt”).
If the full path of a renamed content file exceeds the system path limits then
the file is renamed again using the AppendSequenceID scheme. Content
files associated with CAD documents are only renamed when duplicates exist.
Content files associated with all other type of business object are always
renamed, even when no duplicates exist. This scheme is intended to maintain
consistent content file names between two or more separate exports.
For example, the following causes the prepend object identity scheme to be used
to eliminate duplicate content file names during export.
< ExportOnlyContentFileNaming>PrependIdentity</
ExportOnlyContentFileNaming>
Default value: AppendSequenceID
Note
In addition to enabling the ExportAuditLevelFullMemberInfo, you
have to enable an Export event based on instructions in the “Configuring
Audit Event Recording” topic in the Windchill Help Center.
ImportAuditLevelFullMemberInfo
The ImportAuditLevelFullMemberInfo property determines if an audit
event is emitted for only the received delivery being imported, or for each of the
members being imported in addition to the received delivery.
• Default value is 'true' for collector-based package types
• Default value is 'false' for replication packages
Note
In addition to enabling the ImportAuditLevelFullMemberInfo, you
have to enable an Import event based on instructions in the “Configuring
Audit Event Recording” topic in the Windchill Help Center.
DomainOverride
The DomainOverride property specifies the domain that a package type is
created in. If it is not defined, then a package is created in the domain defined by
the Package preference “Default Domain Path for Packages”.
For example, the following tag results in this package type being created in the
“MyDomain” domain instead of the “Default” domain as defined by the
Package preference “Default Domain Path for Packages”:
<DomainOverride>/MyDomain</DomainOverride>
• Default value: None. If not specified, then a new package is created in the
domain defined by the Package preference “Default Domain Path for
Packages”.
DisableAccessControlOnLinkExport
The DisableAccessControlOnLinkExport property controls whether
access control is disabled when links are processed during package exports.
Enabling this property allows a link which refers to a role object which is
inaccessible to the principal performing the zip to still be exported even if the link
export handler accesses and includes information from the role objects in its
export metadata. When disabled, links which refer to role objects inaccessible to
the principal performing the zip are filtered out of package exports. This property
only applies to importable package exports.
Default value is 'false'.
The following link handlers include role information in their metadata:
Link Handler Description
ExpImpForEPM- Container path of role A object
ContainedIn.java
ExpImpForEPMVar- Container paths of role objects
iantLink.java
ExpImpForModelI- Container path of role A object
temContainedIn.java
ExpImpForEPM- Container paths of role objects
BuildRuleAssocia-
tionLink.java
ExpImpForEPMDe- Container paths of role objects
scribeLink.java
ExpImpForEPMRe- Container paths of role objects
ferenceLink.java
ExpImpForEPM- Container paths of role objects
MemberLink.java
DefaultSupportedDowngradeReleases
This is a site level property to configure default downgrade releases. This is a
subset of the supported downgrade releases for the current release. The releases
which are configured in this property are selected by default on the ZIP Package
for Delivery page while creating a ZIP file. For more information, see Downgrade
Releases.
For example, if the downgraded deliveries feature is supported for Windchill
11.0.M020 and Windchill 11.0.M030 releases and you set the below
configuration.
<DefaultSupportedDowngradeReleases>
<DowngradeRelease>11.0.M030</DowngradeRelease>
</DefaultSupportedDowngradeReleases>
It sets the default downgrade release to Windchill 11.0.M030. It should mention
the internal product name and not the display name.
This is an optional property and if it is not configured, all the available supported
downgrade releases are used for creating downgraded deliveries. For the above
example, if this property is not configured then downgraded deliveries for the
releases Windchill 11.0.M020 and Windchill 11.0.M030 are created.
Default Values are, all the available supported downgrade releases.
Invalid Properties
The following are invalid properties for ReplicationPackage and it's
subTypes :
• RetainCollectionResults
• EnableContentControl
• CollectorId
• ExcludedSeedTypes
• ExcludedMemberContentRoles
• ExportOnlyContentFileNaming
Invalid Values
The following are invalid values for ReplicationPackage and it's
subTypes :
• “Interactive” is invalid value for ManifestOption and OOTB default
value is “None”. “None” & “Static” are only valid values for
ManifestOption.
<IncludedManifestOptions>
<ManifestOption default="true">None</ManifestOption>
</IncludedManifestOptions>
• “Non_Importable_Types “ is invalid values for DeliveryFormat
and OOTB default values is “Windchill_Importable_Types”.
<IncludedDeliveryFormatOptions>
<DeliveryFormat default="true">
Windchill_Importable_Types
</DeliveryFormat>
</IncludedDeliveryFormatOptions>
• “Incremental manifest” is invalid value for DeliveryOption and an
OOTB default value is “Incremental”. “Full” & “Incremental” are only valid
values.
<IncludedDeliveryOptions>
<DeliveryOption>Incremental</DeliveryOption>
</IncludedDeliveryOptions>
Background
This information details configuration and customization hooks for the following
two scenarios:
• Identifying matching users in the target system during context replication
package import and determining when replicated users are created.
During a context replication package import, user data may be included for
object attributes such as “creator” in the delivery ZIP files. By default, user
names are used to identify users on the target system if there is not an exact
match to the user’s distinguished name. If a matching user is not found in the
target system, it may result in the creation of a replicated user, if that is the
chosen resolution. You can change how users are identified in context
replication package import, and instead of user name, the user’s email address
can be used to identify users on the target system. It is also possible to change
this to use custom logic based on other attributes of the user.
• Identifying a replicated user when it comes time to activate/convert to an
active user.
Replicated users created during the Context Replication Package Import
represent inactive users that are known to the Windchill installation but who
cannot log into Windchill or interact with its business objects. Replicated users
can become regular users on activation. Activation occurs automatically when
in the process of creating a new “active” user, the system locates a matching
Replicated user entry for that user and converts that instead. By default, the
user name of the user being created is used to identify a matching Replicated
user to activate.
Sites can change how a Replicated user is identified during activation, and
instead of the user name of the user that is being created, the email address of
that user can be used to identify an existing Replicated user. It is also possible
to change this to use custom logic based on other attributes of the user being
created.
Intended Outcome
By using the configuration or customization strategies described in this section,
you are able to change the behavior of:
• How matching users in the target system are identified during Context
Replication Package Import
• How replicated users are identified when it comes time to activate/convert to
an active user
Prerequisite knowledge
To achieve the intended outcome, you need to have an understanding of the
following:
• Basic development involving JAVA, XML
• Basic understanding of the Service Delegate infrastructure
Solution Elements
These elements determine how matching users in the target system are identified
during Context Replication Package Import.
Note
In the following, the selector value is a pre-determined designator of the
usage context and is meant for identifying the service configuration
appropriate for a specific usage. The selector value must not be modified –
only the corresponding serviceClass value may be changed
Note
This configuration is only supported for the selector
UserInContextReplicationImport. It does not apply to the
selector DisabledUserInContextReplicationImport since
there are no alternative delegate implementations for the selector
DisabledUserInContextReplicationImport other than the
default one configured OOTB.
• To change the behavior to use more customized logic based on other attributes
of the user, see Customization Points and Limitations on page 1624.
Note
In the following, the selector value is a pre-determined designator of the
usage context and is meant for identifying the service configuration
appropriate for a specific usage. The selector value must not be modified –
only the corresponding serviceClass value may be changed
Procedure
• To change the behavior so that user’s email addresses are used to identify
replicated users during user activation, change the serviceClass
associated with the selector ReplicatedUserForActivation to use the
WTPrincipal wt.org.PrincipalMatchDelegate.match(WTPrincipal
querySpec) throws WTException
The PrincipalMatchDelegate interface specifies one single API: public
WTPrincipal match(WTPrincipal querySpec) throws
WTException;
This API finds a match among existing principals based on rules that are
applicable to a usage context.
Sample Code
Writing a Custom Delegate
A custom delegate would implement the PrincipaMatchDelegate and
override the match(…) API to provide some custom logic. The following
example shows the logic for finding a match by user name:
public WTPrincipal match(WTPrincipal querySpec) throws WTException
{
result = OrganizationServicesHelper.manager.findPersistedUser
userNames, null /* email */, null /* fullName */, null /* surname
*/, null /* status */, null /* internal */, Boolean.FALSE /*
disabled */);
return result;
}
Packaged Samples
• <Windchill>\prog_examples\principal\
principalmatchdelegate\
ImportedUserByUserNameMatchDelegate.java
• <Windchill>\prog_examples\principal\
principalmatchdelegate\
ReplicatedUserForActivationByUserNameMatchDelegate.
java
Background
As a part of the default implementation rules are defined to reconcile the decisions
taken by user over the package maturity like for update of package contents,
SaveAs or Revise action where the explicit user decisions are copied forward over
the contents present in target package. The default implementation can be
customized to extend the behavior that suit the respective business requirement.
The default implementation provided copies the user explicit decisions from the
latest versions in the old package to the new versions in the updated package.
Scope/Applicability/Assumptions
• This information should be applied by a developer or customizer who is
responsible for configuring the information page for some object in Windchill.
• It is assumed that you have basic knowledge about Packages and Select Files
functionality.
Intended Outcome
The intended outcome will depend on the implementation as per the respective
business requirement.
Solution
A custom java class would be written which would override the default behavior
for copy forward of explicit decisions on package update.
Prerequisite knowledge
To achieve the intended result you need to have an understanding of the following:
• Basic knowledge about Packages and Select Files.
• Basic knowledge of object versioning in Windchill.
• The management of properties files in Windchill, including the use of
xconfmanager.
Change the following serviceClass attribute with the fully qualified name
of the new custom implementation class.
<Service name="com.ptc.windchill.contentcontrol.delegates.
ContentControlDecisionVersionDelegate">
<Option serviceClass="<custom class>"
requestor="java.lang.Object"
selector="null"
cardinality="singleton"/>
</Service>
Customization Points
The ContentControlDecisionVersionDelegate interface a single API
void opyExclusionInfoForRevision(WTKeyedMap masterToOldCClMap,
WTKeyedMap masterToNewCClMap) throws WTPropertyVetoException ;
The parameters are as follows:
• masterToOldCClMap : WTKeyedMap; : This map contains the master
object as key and the list of old ContentControlLinks as value
• masterToNewCClMap : WTKeyedMap; : This map contains the master
object as key and the list of new ContentControlLinks as value
By getting the list of old and new ContentControlLinks for the same master
the exclusion info can be copied from the old links to the new links. The list of
new ContentControlLinks does not have the ContentControlLinks
for which the same version exists in the old links. For this the exclusion info will
be copied from the old links by default. Only the versions which did not exist
earlier will be added to the list.
Sample Code
The default implementation for this functionality is provided as
DefaultContentControlDecisionVersionDelegate in the
com.ptc.windchill.contentcontrol.delegates package.
Note
For more information on the utility, see the “Windchill Package Command
Line Utility” topic in the Windchill Help Center.
Windows
In following sample, the upload_import_rd.cmd script is run every 8 hours.
schtasks /create /tn "Context Replication cron job" /tr
"C:\import_scripts\upload_import_rd.cmd /sc hourly 8
@echo off
GOTO EXECUTE
:EXECUTE
cd C:\ptc\Windchill\bin
windchill.exe com.ptc.windchill.rd.cli.WindchillPackage import -u demo
-c "/wt.inf.container.OrgContainer=Demo Organization/
wt.pdmlink.PDMLinkProduct=NI_import"
-l "C:\Packages" -r -d
GOTO END
:IMPORT_FAILURE
ECHO [Error] Import command has failed. Please see logs for details
:END
In the following sample, the shell script runs the upload and import commands in
sequence and the input of the upload is redirected in a file. This file is then given
as input to an import command, so that import is started for only those received
deliveries which are uploaded in the same script.
#!/bin/sh
java com.ptc.windchill.rd.cli.WindchillPackage import -u wcadmin
-l
“D:\packages” -c “/wt.inf.container.OrgContainer=Demo Organization/
wt.pdmlink.
PDMLinkProduct=Drive System” -d -m
IF [$?= 1]then exit 1
fi
exit 0
Note
Nothing is collected for replication package members, which are not parts or
CAD documents.
For collected dependents, the latest iteration of each released revision and the
latest iteration of any un-released revisions are included in the collection. For
example, assume a part has the following versions:
• A.1 (Released)
• B.1 (In Work)
• C.1 (Released)
• D.1 (In Work)
• D.2 (In Work)
• E.1 (In Work)
• E.2 (In Work)
The following versions are collected:
• A.1 (Released)
• B.1 (In Work)
• C.1 (Released)
• D.2 (In Work)
• E.2 (In Work)
Note
• The additional related objects (non-child objects) are collected only from
those objects which are selected via the initial configuration specification
(LATEST). They are not collected from subsequently gathered versions.
For example, if Part B revision 2 of a child part is selected by the
configuration specification LATEST, then the collector gathers change
objects, documents that are related to Part B revision 2. If Part A revision 2
of the part is RELEASED then it is included in the package but it’s related
objects (change objects, documents etc.) are not included in the package.
• Standard access control is applied during collection so only objects
accessible to the person performing the refresh are collected.
Usecase 1
One Change Activity missing for Change Notice and Changeable (Part)
• Create Part1 and Part2.
• Create Change Request for this Part1
• Create Change Notice for the Change Request.
• Change Task >> Add Part2 as Affected Object.
• Change Notice >> Implementation Plan >> Add Change Task2 and add Part2
as Affected Object.
• Set Change Task2 lifecycle state to “Under Review”.
When there are multiple changeable associations linking same changeable to same
change notice the changeable/change notice are not recorded as missing objects
for the second change activity. Only the change activity is recorded as missing
object.
Scenario Result
CR — C (Part1)
CR — CN — CA1 — C (Part2)
CR — CN — CA2 — C (Part2) CA2 is recorded as missing for both CN
and C.
Usecase 2
Change Notice and Change Task missing for Changeable (Part)
• Create Part.
• Create Change Request for that Part.
• Create Change Notice for the Change Request.
• Go to the Change Task and add part as Affected Object
• Move Change Notice to other context. Change Task will also move to other
context.
• Create a replication package
Source Object Missing Object
Part Change Notice
Part Change Task
Usecase 3
Change Task missing for Changeable (Part) and Change Notice
• Create Part.
• Create Change Request for that Part.
• Create Change Notice for the Change Request.
• Go to the Change Task and add part as Affected Object.
• Create missingchangeuser and absolute deny read permission for Change
Task.
• Create replication package using missingchangeuser
Source Object Missing Object
Change Notice Change Task
Part Change Task
When a Change Task is linked to a Changeable (part) and Change Notice, but the
permission to read are denied for the Change Task, then over replication the
Change Task is recorded as the missing object for the Part as well as the Change
Notice.
Scenario Result
CR — CN — CA – C
CR — CN — CA – C CA is recorded as missing for C and CN
Usecase 4
Change Task and Changeable(Part) missing for Change Notice
• Create Part1 and Part2.
• Create Change Request for this Part1
• Create Change Notice for the Change request.
• Go to the Change Task and add Part2 as Affected Object
• Move part2 to another context
• Create replication package
When there are multiple Changeable (Part) associations linked to same Change
Notice and Change Request, the Changeable and Change Request are recorded as
missing objects for the Change Notice.
Scenario Result
CR — C (Part1)
CR — CN — CA — C (Part2) CA and C (Part2) is recorded as missing
for CN.
Usecase 5
Changeable(Part) missing for Change Notice and Change Task
• Create Part1 and Part2.
• Create Change Request for that Part1.
• Create Change Notice for the Change Request.
• Go to the Change Task and add Part2 as Affected Object
• Move part2 to another context.
• Create replication package
Source Object Missing Object
Change Notice Part2
Change Task Part2
When there are multiple Changeable (Part) associations linked to same Change
Notice and Change Request, the Changeable (Part2) is recorded as missing objects
for the Change Activity and Change Request.
Scenario Result
CR — C (Part1)
CR — CN — CA — C (Part2) C (Part 2) is recorded as missing for
both CN and CA.
Usecase 6
Change Notice missing for Change Task and Changeable(Part)
• Create Part1 and Part2.
• Create Change Request for this Part1.
• Create Change Notice for the Change request.
When there are multiple Changeable (Part) associations linked to same Change
Notice and Change Request, the Change Notice is recorded as missing object for
the Change activity and Changeable (Part 2).
Scenario Result
CR — C (Part 1)
CR — CN — CA — C (Part 2) CN is recorded as missing for both CN
and C (Part 2).
Note
To execute usecase 1 and 3, enable
DisableAccessControlOnLinkExport of replication package in
WPTypeBasedPropertyLoader.
Usecase 1
• Create a Part1 in Context A.
• Create two parts Part2 and Part3 in Context B.
• From Context A, add Part2 as the child of Part1 and create Part3 as the
substitute of the Part2.
• Check-in Part as required.
• Create replication package of Context A.
• Missing object tab of Context A will show relation between Part1 <-> Part2.
(This relation is due to WTPartUsageLink).
• Create replication package of Context B.
• Missing object of Context B will not show any missing object.
Note
Following links are child only links and therefore missing object will be
reported only if child of these links are in another context and the replication
package is created on the parent context.
• WTPartUsageLink
• WTDocumentUsageLink
• EPMMemberLink
Usecase 1
• Create a Part1 in Context A.
• Create two parts — Part2 and Part3 in Context B.
• From Context A, add Part2 as the child of Part1 and create Part3 as the
alternate of the Part2.
• Check-in part as required.
• Create replication package of Context A.
• Missing object tab of Context A will show relation between Part1 <-> Part2.
(This relation is due to WTPartUsageLink).
• Create replication package of Context B.
• Missing object of Context B will not show any missing object.
<Property name="com.ptc.windchill.wp.missingObject.receipientAndContext1
default="testuser:$com.ptc.windchill.wp.missingObject.myUserContexts"/>
<Property name="com.ptc.windchill.wp.missingObject.receipientAndContext2=
uid=windchilluser,ou=people,cn=administrativeldap,cn=windchill_11.2,o=
ptc|
Ldap.ptcnet.ptc.com|Ldap.ptcnet.ptc.com:$com.ptc.windchill.wp.missingOb
ject.
myUserContexts/>
Note
The location of the DTD files is as follows:
• Windchill 11.1 M020: Windchill/loadXMLFiles/
standard11_1.dtd
2. Identify the XSL transformation pattern for the changes. For more details
about the scenarios and examples, refer XSL Transformation Scenarios on
page 1664.
3. Update the release specific XSL template and check in corresponding folders
of respective source variant.
4. Extract them to release specific folder present in codebase/registry.
Note
XSL templates are created based on DTD element structure defined in
source DTD. You have to modify the respective XSLs. Do not alter the
inclusions.
Example
Attribute Attr1 is newly added to WTPart DTD in Windchill 11.2.0.0.
During the creation of downgrade deliveries for Windchill 11.1 M020 Attr1
should be filtered as part of XSL changes. You need to update OOTB checked in
WTPart.xsl present in $(wt.codebase.location)/registry/
XSLRepo/11.1.M020/WTPart.xsl.
Note
• Run this tool in the offline mode.
• Run this tool for OOTB XPATH filter and Customization filters.
• The indexes on XMLDocument table are checked to verify this tool.
• This tool is supported only for Oracle Database in the Windchill
11.2.0.0 release.
• Check the SQL plan, the query which uses XPATHs, to verify the XDB
index usage during XPATH filter.
• Refer to Oracle administrative information on XDB Index for mode
details.
XMLFilterEntry
By default, for all root tags, default XML filter entry carries information about
localId and ufid. But usagelinkfilter entry must contain its role A and
role B information also when it is queried.
Example
package com.ptc.transformation.filter.test;
import com.ptc.transformation.core.TransformationException;
import com.ptc.transformation.filter.DefaultXMLFilterEntry;
This overrides the initialize method to add few more tags as part of identity keys.
WTPartUsageLinkFilter entry can be configured through Windchill service
delegate factory pattern as shown below:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Configuration SYSTEM "xconf.dtd">
<Configuration targetFile="codebase/service.properties">
<Service context="default" name=
"com.ptc.transformation.filter.DependencyFilter">
<Option cardinality="duplicate" requestor="java.lang.Object" selector=
"UsageLink" serviceClass=
"com.ptc.transformation.filter.test.UsageLinkFilter" />
</Service>
You can configure your entries in your module specific service configuration.
UsageLinkFilter
Usage link filter is a sample Dependency filter which filters
WTPartUsageLink if any WTPart role A or WTPart with master ufid is in
role B.
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.ptc.transformation.core.TransformationContext;
import com.ptc.transformation.core.TransformationException;
import com.ptc.transformation.filter.DefaultDependencyFilter;
import com.ptc.transformation.filter.DependencyFilterPriority;
import com.ptc.transformation.filter.FilterIdentityKey;
import com.ptc.transformation.filter.XMLFilterEntry;
import com.ptc.transformation.filter.XMLLookUpService;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
@FilterIdentityKey(keys = { "WTPart"})
public class UsageLinkFilter extends DefaultDependencyFilter {
public static final String ROOT_TAG = "WTPartUsageLink";
public static final String usedByPath = "WTPartUsageLink/usedBy/
ObjectReference/ufid";
public static final String usesPath = "WTPartUsageLink/uses/
ObjectReference/ufid";
@Override
public Collection<XMLFilterEntry> execute(Collection<XMLFilterEntry>
inputEntries, TransformationContext context)
throws TransformationException {
Collection<XMLFilterEntry> usageLinkEntries = new HashSet<>();
Set<String> masterUfids = new HashSet<>();
Set<String> ufids = new HashSet<>();
for (XMLFilterEntry xmlFilterEntry : inputEntries) {
for (Map.Entry<String, String> entry :
xmlFilterEntry.getIdentityEntries().entrySet()) {
String key = entry.getKey();
if (key.contains("/masterUfid")) {
masterUfids.add(entry.getValue());
}
if (key.contains("/ufid")) {
ufids.add(entry.getValue());
}
}
@Override
public int getPriority() {
return DependencyFilterPriority.LINK_OBJECT_PRIORITY;
}
}
@Retention(RUNTIME)
This defines the required dependent tags and additional filter identity required for
its processing. In this case, it requires masterUfid as part of Part filter
identity key, so it gets annotated as shown below:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Configuration SYSTEM "xconf.dtd">
<Configuration targetFile="codebase/service.properties">
<Service context="default" name=
"com.ptc.transformation.filter.DependencyFilter">
<Option cardinality="duplicate" requestor="java.lang.Object" selector=
"UsageLink" serviceClass=
"com.ptc.transformation.filter.test.UsageLinkFilter" />
</Service>
Transformation Filter
Filters are the artefacts provided to remove XML files from downgrade delivery
zip which are not applicable for a given target release. Transformation filters can
be name-based, XPath-based or a Java-based type.
It is assumed that application developers who perform these configurations have
expertise in JAVA, XML and XSL.
Element Handlers
Element handlers are the transformation invokers based on the Java
transformation API. These element handlers can be configured for a given element
tag. Transformation happens in the following three phases for each element:
1. Pre-Process phase, sets the operations required for preparing XML files for
transformation. This is required for use cases which cannot be handled through
XSL. Object owners can decide the pre-process method to provide their pre-
processing logic. Framework calls the pre-process of the registered element
handlers for attributes.
2. Transform phase, transforms an XML file to target XML file based on the
configuration set in XSL.
3. Post-Process phase, involves the transformed XML documents and validation
activities for element transformation processing. Object owners can decide on
the post-process method to provide their post-processing logic. The framework
calls the post-process of the registered element handlers for attributes.
Content Transformation
Contents are copied during the downgrade process by default. To update the
content in the downgrade process, perform the following:
1. Create an element handler by extending from
XSLTransformElementHandler. Overrode the method is
ContentTransformationRequired to return true.
Guidelines
• Implementing the DependencyFilter interface directly is not
recommended. DependencyFilter customization must involve extending
DefaultDependencyFilter and provide implementation for execute
method in it.
• If a dependency filter depends on multiple objects, then you must define
multiple FilterIdentity annotations.
• Customized DependencyFilter must define the
DependencyFilterPriority as shown below:
package com.ptc.transformation.filter;
private DependencyFilterPriority() {
// This is not be instantiated. Should be used for static references
only
}
Note
You can provide your own filter priority definitions based on your
object models and relations.
removeFil
tered flag
getInstance Transforma XMLLookUpSer Always use this
tionContext vice instance method to get
initialized for a XMLLookUpSer
given vice instance.
Transforma This ensures that
tionContext. all the operations
happen under one
downgrade
delivery and
corresponding base
delivery referred
XMLs.
<xsl:style
sheet
version=
"1.0"
xmlns:xsl=
"http://
www.w3.org/
1999/XSL/
Transform">
<xsl:template
match="@* |
node()">
<xsl:copy>
<xsl:apply-
templates
select="@* |
node()"></
xsl:apply-
templates>
</xsl:copy>
</xsl:tem
plate>
<xsl:template
match=
"FederationIn
fo">
</xsl:tem
plate>
</xsl:style
sheet>
Renaming the FederationIn NewFederatio <?xml
element fo nInfo version=
"1.0"
encoding=
"UTF-8"?>
<xsl:style
sheet
version=
"1.0"
xmlns:xsl=
"http://
www.w3.org/
1999/XSL/
Transform">
<xsl:template
match="@* |
node()">
<xsl:copy>
<xsl:apply-
templates
select="@* |
node()"></
xsl:apply-
templates>
</xsl:copy>
</xsl:tem
plate>
<xsl:template
match=
"FederationIn
fo">
<NewFederatio
nInfo>
<xsl:copy-of
select=
"*"></xsl:co
py-of>
</NewFedera
tionInfo>
</xsl:tem
plate>
</xsl:style
sheet>
</xsl:copy>
</xsl:tem
plate>
<xsl:template
match=
"createdBy/
WTPrincipalRe
ference/
@fullName">
<xsl:copy-of
select="." />
<xsl:attri
bute name=
"firstNa
me">Added
FirstName</
xsl:attri
bute>
</xsl:tem
plate>
</xsl:style
sheet>
Remove an isInternal is isInternal is <?xml
attribute an attribute of not available version=
isInternal WTPrincipalRe "1.0"
from created by ference encoding=
WTPrincipal "UTF-8"?>
Reference <xsl:style
sheet
version=
"1.0"
xmlns:xsl=
"http://
www.w3.org/
1999/XSL/
Transform">
<xsl:template
match="@* |
node()">
<xsl:copy>
<xsl:apply-
templates
select="@* |
node()"></
xsl:apply-
templates>
</xsl:copy>
</xsl:tem
plate>
<xsl:template
match=
"createdBy/
WTPrincipalRe
ference/
@isInter
nal">
</xsl:tem
plate>
</xsl:style
sheet>
Renaming of an fullName newFullName <?xml
attribute version=
"1.0"
encoding=
"UTF-8"?>
<xsl:style
sheet
version=
"1.0"
xmlns:xsl=
"http://
www.w3.org/
1999/XSL/
Transform">
<xsl:template
match=
"@*|node()">
<xsl:copy>
<xsl:apply-
templates
select="@* |
node()"></
xsl:apply-
templates>
</xsl:copy>
</xsl:tem
plate>
<xsl:template
match=
"WTPrincipal
Reference">
<xsl:copy>
<xsl:apply-
templates
select="@* |
node()"></
xsl:apply-
templates>
</xsl:copy>
</xsl:tem
plate>
<xsl:template
match=
"WTPrincipal
Reference/
@fullName">
<xsl:attri
bute name=
"newFull
Name">
<xsl:copy-of
select="*" />
</xsl:attri
bute>
</xsl:tem
plate>
</xsl:style
sheet>
Split the value of FullName = FirstName = <?xml
an attribute into Demo,User Demo, LastName version=
two different = User "1.0"
attributes encoding=
"UTF-8"?>
<xsl:style
sheet
version=
"1.0"
xmlns:xsl=
"http://
www.w3.org/
1999/XSL/
Transform">
<xsl:template
match="@* |
node()">
<xsl:copy>
<xsl:apply-
templates
select="@* |
node()"></
xsl:apply-
templates>
</xsl:copy>
</xsl:tem
plate>
<xsl:template
match=
"createdBy/
WTPrincipalRe
ference/
@fullName"
select=
"$firstName"
/></xsl:attri
bute>
</xsl:if>
<xsl:if test=
"$lastName">
<xsl:attri
bute name=
"lastNa
me"><xsl:val
ue-of
select=
"$lastName"
/></xsl:attri
bute>
</xsl:if>
</xsl:if>
</xsl:tem
plate>
</xsl:style
sheet>
Merge WTPart1, WTPart1, WTPart To be done in Java
WTPArt2 to form WTPart2 delegates.
WTPart
Split WTPart into WTpart WTPart1, To be done in Java
WTPart1, WTPart2 delegates.
WTPart2
Caution
The custom properties limit in Microsoft Office documents is 255 chars. This
limit can be enforced by a string length constraint in the Type and Attribute
Management utility.
Note
To find the introspection name (the <wt_name> value), open a Windchill
shell and execute the InfoReport command for a specific object type.
For example:
InfoReport wt.doc.WTDocument
<attribute>
<ms_name>Created By</ms_name>
<wt_name>creator.name</wt_name>
<display>true</display>
<attrFormat>string</attrFormat>
</attribute>
<attribute>
<ms_name>Modified By</ms_name>
<wt_name>modifier.name</wt_name>
<display>true</display>
<attrFormat>string</attrFormat>
</attribute>
<attribute>
<ms_name>Created On</ms_name>
<wt_name>thePersistInfo.createStamp</wt_name>
<display>true</display>
<attrFormat>string</attrFormat>
</attribute>
</type>
Note
The attributes label and screentip control the label and the tooltip for
the button respectively. In general, static text marginally improves
performance.
To localize a custom menus, you must use getLabel and getScreentip
instead.
Localizing Text
Windchill Desktop Integration allows a way to localize the text displayed on the
ribbon UI. This enables end users to see translations in their native languages.
Note
In this example, method and serverAction are actually implemented on
the client and the server respectively. Each attribute value should be
accompanied with implementation.
Otherwise, an Action not found error will be displayed by Windchill
Desktop Integration.
Note
PTC recommends that the macros be thoroughly tested using live Microsoft
Office documents before being uploaded on the Windchill server for
deployment. Windchill Desktop Integration is not responsible for any
exceptions arising during macro execution. All errors are displayed to the
users.
Note
The macro_name key is a reserved and mandatory keyword.
The macro_args is optional and can be used in case additional data needs to
be provided to the macro.
Note
The Windchill Desktop Integration client automatically picks up all
modules on the subsequent connect action on the server.
Note
If the value of module path parameter is not an absolute path, then it is
expected to be the relative path from the custom folder.
Removing Macros
To remove the macro in the Microsoft Office document after it has been run, use
the following action configuration:
<action method="remove_module" type="CLIENT">
<defaultdata key="module_name">Module1</defaultdata>
</action>
The module_name key value should match with what is displayed as the
module name in the VBA editor (Alt + F11).
This is the configuration for the test_action action defined for objects of type
test_object. Invocation of this action would launch Test.jsp. On
completion of interaction with the user interface rendered by this page, a response
is built in TestFormProcessor and can be passed on to the client, if desired.
Implementation Example
In the following example, the user needs to select a set of Windchill parts and
query certain properties of these selected parts. We add these properties in a
Microsoft Excel sheet in the form of column headers. The properties to be selected
and its sequence will be provided as an input to the Windchill server. The response
from the server would be picked up by the client and will be populated in a tabular
form in the Microsoft Excel sheet.
A working example of this example is also available in the Windchill installation.
To deploy the sample, use a Windchill shell and perform the following actions:
1. Navigate to prog_examples/DTI_Customization.
2. Under each src and src_web folder, find and invoke the ant script named
build.xml. The file DTICustomizationReadMe.txt is included for
quick reference.
Client-Side Customization
Customize the Ribbon UI
1. Locate the following file:
<Windchill>/codebase/com/ptc/windchill/enterprise/
nativeapp/msoi/client/custom/wtCustomMenu.xml
2. Add the following text to the file:
<?xml version="1.0"?>
<groups>
<group id="ExcelActionsGroup" tag="ExcelActionsGroup"
label="Excel actions group"
screentip="Custom Excel actions group" visible="true">
<button id="SearchParts" tag="SearchParts" enabled="true"
label="Search parts" screentip="Sample custom action to
search
parts on the Windchill server."
getImage="MsoiGetImage" onAction="MsoiOnAction" keytip="sp"/>
</group>
</groups>
The next time a Windchill Desktop Integration client running Microsoft Excel
connects to this server, the updated ribbon UI definition will be downloaded to
the client cache.
3. Close Microsoft Excel and launch it again. This step is necessary because the
Windchill add-in will load in the Microsoft Office application (Excel) even
before connecting to any Windchill server. When Microsoft Excel is launched
a second time, you should be seeing a new group and an action:
Note
The name of the macro GetHeaders must match the action
configuration data parameter macro_name.
2. Create another macro that will subsequently pick up response from the server
and populate it in the sheet. According to the action configuration, this macro
must be called PutValues. The VBA code for the Microsoft Excel
workbook now looks like the following example:
Note that the code within the PutValues macro above will simply generate an
alert message with the custom response received from the Windchill server. In
practice, the code could do complex actions such as generating an inline
validation drop-down for certain cells.
'A reference to msxml6.dll is needed
Dim dom As New DOMDocument60
dom.LoadXML (strResponse)
With Range("C1").Validation
'Remove previous validation (likely that user redoing a
seed part search)
.Delete
.Add Type:=xlValidateList, _
AlertStyle:=xlValidAlertStop, _
Operator:=xlBetween, _
Formula1:=strNumberChoices
End With
Server-Side Customization
Define the Custom Action
The following file is provided out-of-the-box with Windchill. The file is empty
and can be used for this sample customization:
<Windchill>/codebase/config/actions/custom-actions.xml
Add the following XML text as a child node for the listofactions document
node.
<objecttype name="customization" class="wt.doc.WTDocument">
<action name="DTICustomizationDemo">
<command class="com.ptc.dti.customization.forms.
TICustomizationFormProcessor"
method="execute" windowType="popup"
url="/netmarkets/jsp/customization/partPicker.jsp"/>
</action>
</objecttype>
This defines the DTICustomizationDemo action, which will be called from
the DTI client side. On invocation of this action, a partPicker.jsp is
launched. On completion of this action, a response is built in
DTICustomizationFormProcessor.
<SCRIPT>
function partPickerCallback(objects) {
var selectedPartsOid = '';
var myJSONObjects=objects.pickedObject;
for(var i=0; i< myJSONObjects.length;i++) {
if(i != 0){
selectedPartsOid += ';'; //partOID separator
}
selectedPartsOid += myJSONObjects[i]["oid"];
}
$("selectedParts").value = selectedPartsOid;
window.pickerCallback = "doNothing";
}
</SCRIPT>
Note
• Use the wctags:externalFormData tag to pass DTI data in the form
of hidden field.
• Use dti:getCustomActionArg(param.externalFormData)
to capture the input argument that is send from DTI. It is passed to the
form processor as a hidden field.
In this example, the argument sent is a list of Windchill part properties to query
with ‘::’ as the separator(Name::Number::Version::State).
A pickerCallback function is defined, which will capture OIDs of selected parts
and put it in a string with ‘;’ separators, then pass that list of selected parts OIDs to
form processor through selectedParts hidden field. The following example
displays the partPicker.jsp after searching and selecting a few records:
Server-Side Steps
Tip
Steps 1 and 2 can either be performed manually or using the Ant script located
under the src and src_web folders in the following directory:
<Windchill>/prog_examples/DTI_Customization
<action name="DTICustomActionStep">
<command windowType="popup" url="/netmarkets/jsp/customization/
dtiCustomActionStep.jsp"/>
</action>
<action name="DTICustomActionForMulti">
<command class="com.ptc.dti.customization.forms.
DTICustomActionForMultiFormProcessor"
method="execute" windowType="popup"
url="/netmarkets/jsp/customization/
dtiCustomActionForMulti.jsp"/>
</action>
<action name="DTICustomActionFolder">
<command class=
"com.ptc.dti.customization.forms.DTICustomActionFormProcessor"
method="execute" windowType="popup"
url="/netmarkets/jsp/customization/dtiCustomActionFolder.jsp"/>
</action>
</objecttype>
<model name="DTI.Explorer.Document.SingleSelect.Custom.RMB">
<action name="DTICustomAction" type="customization"/>
<!-- DTI Custom Action -->
</model>
<model name="DTI.Explorer.Folder.SingleSelect.Custom.RMB">
<action name="DTICustomActionFolder" type="customization"/>
<!-- DTI Custom Folder Action -->
</model>
</actionmodels>
Or run the Ant script located under the src and src_web folders under
<Windchill>/prog_examples/DTI_Customization.
Implementation Example
The following example adds a New Link action to Windows Explorer.
1. Add the following lines to <Windchill>\codebase\config\
actions\custom-actionsModels.xml:
<model name="DTI.Explorer.Folder.SingleSelect.Custom.RMB">
<action name="add_link" type="bookmark" /> < !-- New Link -->
</model>
2. Add the following lines to <Windchill>\codebase\com\ptc\
windchill\enterprise\nativeapp\msoi\client\custom\
wtCustomExplorerActions.xml:
<command key="add_link">
<action serverAction="bookmark.add_link" type="WIZARD"/>
</command>
3. Restart the method server.
4. Close Windows Explorer and stop WTWindows.exe.
5. Restart Windows Explorer and connect to the Windchill server.
1701
Writing Custom Windchill ProjectLink
Algorithms
This information applies when performing the following Windchill ProjectLink
configuration steps:
Configuring Automatic Status Calculation on page 1735
Configuring Automatic Deadline Calculation on page 1728
Note the following guidelines:
• Always add logging statements at the appropriate locations. This will help
when troubleshooting any issues.
• To invoke a custom algorithm on the basis of some change in a deliverable
subject object, throw the ProjectManagementEvent.EPP_DELIVERABLE_
SUBJECT_CHANGE event in the operation that is causing the change.
% Work Complete
Description Captures changes in the percentage of work completed for
the activity and subplan.
Event Constant ProjectManagementEvent.EPP_PERCENT_CHANGE
Note
To invoke a custom algorithm on the basis of some
change in a deliverable subject object, throw this event in
the operation that is causing the change.
Event Constant ProjectManagementEvent.EPP_DELIVERABLE_
SUBJECT_CHANGE
Note
You will need the CustomDeadlineImplementation
class to throw this event. For more information, see the
examples provided in Construct a Deadline Algorithm for
Individual Activities on page 1730.
Event Constant ProjectManagementEvent.EPP_CUSTOM_DEADLINE_
CHANGE
Note
This event is only available after additional
configuration. See the section below.
Event Constant ProjectManagementEvent.EPP_DATE_CHANGE
Note
Out of the box, the Current Date Change event listener does nothing. You can
extend the listener using the details below.
Best Practice
As a best practice, to retain the existing listener configurations you should
consider calling super.performStartupProcess() inside the overridden
performStartupProcess().
If you are implementing an algorithm for deadline calculation, add an entry for the
custom to projectmanagement.wt.properties.xconf under com.ptc.
projectmanagement.plan.EPPCustomEventHandlerService:
<Property default=
"com.ptc.projectmanagement.plan.EPPCustomEventHandlerService/
com.ptc.projectmanagement.plan.StandardEPPCustomEventHandlerService"
name="wt.services.service.3715"
/>
If you are implementing an algorithm for deadline calculation, add an entry for the
custom to projectmanagement.wt.properties.xconf under com.ptc.
projectmanagement.plan.HealthStatusEventHandlerService:
<Property default=
"com.ptc.projectmanagement.plan.HealthStatusEventHandlerService/
com.ptc.projectmanagement.plan.StandardEPPCustomEventHandlerService"
name="wt.services.service.3715"
/>
Note
For more information, see Custom Handler Guidelines for Status and Deadline
Calculation on page 1707.
Roll-Up Handlers
Currently the listener code would receive the collection of summary activities,
calculate their status or deadline, and invoke the roll up API in the
StandardEPPCustomEventHandlerService class.
Tip
The EPPCustomUtils.java class provides helper APIs to retrieve data based
on certain inputs.
• PlannableHelper.service.getLeafActivitiesForSummary(plannable)
Returns WTCollection of individual activities (leaf activities or suplans) for a
given summary or plan object.
• AssignmentHelper.service.
getResourceAssignmentsForPlannables(plannables)
Returns WTCollection of resource assignments for the given plan object.
• PlanHelper.service.getPlansFromSummaryActivities(plannables)
Returns WTCollection of plans for a given set of activities.
• PlanHelper.service.getProjectsForPlans(plans)
Returns WTHashSet of projects for a given list of plans.
• PlanHelper.service.getSummaryActivities(plans,false)
Returns WTHashMap of summary activities. The key lists any child
activitieor child subplans
Note
Additional information is available in Registered Event Listeners for Deadline
and Status Calculation on page 1702.
• Custom handlers should only modify HealthStatus and Deadline and should
not modify any other activity attribute.
• Whenever possible, use multi-object APIs (APIs that take a collection as an
argument rather than an individual object). This helps you avoid calling an
API in a loop.
For example, to get all the running plans in the system, you should author the
API as follows:
public WTCollection getActivePlans(){
QuerySpec qs = new QuerySpec();
int idxPlan = qs.appendClassList(Rootable.class, true);
SearchCondition scForActivePlans = new SearchCondition (
Plan.class,
Plan.PLANNABLE_STATE,
SearchCondition.EQUAL,
PlannableState.INPROCESS);
qs.appendWhere(scForActivePlans, new int[] { idxPlan });
PlanResultProcessor resultProcessor = new PlanResultProcessor();
PersistenceServerHelper.manager.query((StatementSpec) qs,
resultProcessor);
WTHashSet plans = new WTHashSet(PersistenceHelper.manager.find(qs));
return plans;
}
Within this map, the event name for the ProjectManagementEvent is provided as
the key, and the list of objects processed as part of that event is the value.
Your custom algorithm can iterate through the key set and find out the objects
processed thus far.
For example, a collection of activities throws two events: EPP_PERCENT_
CHANGE and EPP_FINISH_CHANGE:
1. The EPP_PERCENT_CHANGE event is thrown first.
2. Once it is processed, HashMap is updated as follows:
HashMap("ProcessedEvent", HashMap(EPP_PERCENT_CHANGE, <List of
Objects>));
These overridden methods should return a string containing the image path as
follows - return netmarkets/images/xxxxx.png
For example, below code could be a possible custom algorithm which would
configure health status icon for Activity having health status as ‘RED’:
package com.ptc.projectmanagement.plan;
For type ‘PlanActivity’, there is out of the box handler defined as follows:
<Service context="default" name="com.ptc.projectmanagement.plan.
HealthStatusIconHandler ">
<Option cardinality="singleton" requestor= "null"
selector = "com.ptc.projectmanagement.plan.Plannable" serviceClass=
"com.ptc.projectmanagement.plan.PlannableHealthStatusIconHandler"/>
</Service>
Note
When you configure algorithms for the Deadline and Health Status attributes,
these attributes must be configured as read-only from the Type Manager, so
that manual updates through the user interface are restricted. For more
information, see the online help topic “Working with the Type and Attribute
Management Utility” in the Windchill Help Center.
The event listeners for the above mentioned events (except for POST_MODIFY)
invoke custom algorithms for Deadline and Health Status for variant baseline
member links.
Note
If any subject is not associated with any activity, then there is no entry for
this subject in the return map-WTKeyedHashMap.
Note
If any activity does not have associated Subject of Deliverables, then the
empty ArrayList is returned in the WTKeyedHashMap.
Note
If any activity does not have a parent summary activity and its parent is a
plan, then the empty WTArrayList(PlanActivity) is returned in the
WTKeyedHashMap(PlanActivity, WTArrayList(PlanActivity)).
• DeliverableHelper.service.getActivitiesHavingDeliverableSubjects(activity
Coll): For the given collection of activities, this API returns WTCollection
of activities that have a Subject of Deliverable associated with them.
Note
If any activity has been marked as Deliverable and does not have any
Subject of Deliverable, then it is not included in the collection of activities
that are returned.
Note
In this entry, add custom handler name for serviceClass field:
serviceClass= <custom_handler_name>.
Note
If algorithms for the Deadline and Health Status attributes are not configured
properly or not present in the system, the values of these attributes are blank
for variant baseline objects.
Prerequisites
Before you create custom algorithms, perform the following steps:
1. Create baseline objects.
2. Create a customize view for Baselines Objects or Variant Baselines table with
the Deadline and Health Status columns. For more information, see the online
topic “Customizing Table Views” in the Help center.
3. Add Health Status and Deadline attributes for Floating Baseline Member type
using Type and Attribute Management utility to view these attributes on Variant
@Override
public void
updateFloatingBaselineMemberLinksFromActivity(WTCollection activityList)
try{
updateFBMLlogic(activityList);
}catch(WTException e){
log.error("Execption in
updateFloatingBaselineMemberLinksFromActivity.."+e);
throw new WTException(e);
}
/**
* Method to update FBML objects
* @param activityList
* @throws WTException
* @throws WTPropertyVetoException
*/
private void updateFBMLlogic(WTCollection activityList) throws
WTException, WTPropertyVetoException {
WTKeyedHashMap activitySubjectsMap =
DeliverableHelper.service.getActivitySubjects(activityList);
if(isDebugEnabled){log.debug(" updateFBMLlogic: got
ActivitySubjects list... ");}
WTKeyedHashMap activityToParentMap = new WTKeyedHashMap();
HealthStatusType health =
planActivity.getHealthStatusType();
fbml.setHealthStatusType(health);
fbml.setDeadline(planActivity.getDeadline());
}else{
PersistenceHelper.manager.save(coll);
if(isDebugEnabled){log.debug(" updateFBMLlogic: updated the
collection of FloatingBaselineMember links");}
}
/**
* create activity To fbml List map
* @param activitySubjectsMap
* @param activityToParentMap
* @param actToFBMLmap
* @throws WTException
*/
public void createActToFBMLlistMap(WTKeyedHashMap
activitySubjectsMap, WTKeyedHashMap activityToParentMap,
Map<PlanActivity, WTHashSet> actToFBMLmap) throws WTException {
if(isDebugEnabled){log.debug(" createActToFBMLlistMap: creating FBML To
activity list Map ");}
for(Object key : activitySubjectsMap.keySet()){
ArrayList subjectList =
(ArrayList)activitySubjectsMap.get(key);
WTArrayList list = new WTArrayList();
list.addAll(subjectList);
//TODO: when same part is added to 2 or more activities
WTArrayList subjectListCollection = new WTArrayList();
subjectListCollection.addAll(subjectList);
//- SUPPORTED API
WTKeyedHashMap associatedActivities =
DeliverableHelper.service.getAssociatedActivities(subjectListCollection);
activityToParentMap.putAll(PlannableHelper.service.getAllAncestorsOfActi
vities(actList));
Iterator actIterator =
actList.persistableIterator();
while(actIterator.hasNext()){
//need to create new reference of WTHashSet
for adding fbmlList to map
WTHashSet fbmlListForAddition = new
WTHashSet();
fbmlListForAddition.addAll(fbmlList);
PlanActivity planActivity =
(PlanActivity)actIterator.next();
if(actToFBMLmap.get(planActivity)!=null){
WTHashSet set =
actToFBMLmap.get(planActivity);
set.addAll(fbmlListForAddition);
actToFBMLmap.put(planActivity, set);
}else{
actToFBMLmap.put( planActivity,
fbmlListForAddition);
}
}//while
}// if(fbmlList!=null)
}// if(obj instanceof SubjectOfDeliverable){
}//for(Object obj : subjectList){
}
}
**
* create fbml To ActList map
* @param activityToParentMap
* @param actToFBMLmap
* @param ancestorsSubjectsMap
* @param fbmlToActmap
while(itr.hasNext()){
Set planActList = new HashSet();
Object fbmlObj = itr.next();
if(fbmlObj instanceof FloatingBaselineMember){
FloatingBaselineMember fbml =
(FloatingBaselineMember) fbmlObj;
} if(isBaselineSubjectOfToAncestor){
if(fbmlToActmap.get(fbml)!=null){
fbmlToActmap.get(fbml).add(planActivity);
}else{
planActList.add(planActivity);
fbmlToActmap.put(fbml, planActList);
}
}
}
if(isDebugEnabled){log.debug(" getResultingActivity: resultingAct
"+resultingAct);}
return resultingAct;
}
/**
* check if baseline is added as subject to any of summary activity
* @param baseline
* @param ancestorsSubjectsMap
* @param activityAncestors
* @return
* @throws WTException
*/
while(itr.hasNext()){
Object obj = itr.next();
PlanActivity ancestorActivity = (PlanActivity)obj;
ArrayList list = new ArrayList();
ObjectIdentifier objectIdentifier =
ancestorActivity.getPersistInfo().getObjectIdentifier();
if(ancestorsSubjectsMap.get(objectIdentifier)!=null){
list = (ArrayList)
ancestorsSubjectsMap.get(objectIdentifier);
}
if(list!=null){
if(list.contains(baseline))
{
if(isDebugEnabled){log.debug("
isBaselineSubjectOfActivityAncestors:true , baseline: "+baseline+"
activityAncestors:"+activityAncestors);}
return true;
}
}
}
if(isDebugEnabled){log.debug("
isBaselineSubjectOfActivityAncestors:false , baseline: "+baseline+"
activityAncestors:"+activityAncestors);}
return false;
}@Override
public void updateFloatingBaselineMemberLinks(WTCollection
floatingBaselineMemberList)
throws WTException, WTPropertyVetoException {
isDebugEnabled = log.isDebugEnabled();
if(isDebugEnabled){log.debug(" IN Custom handler:
updateFloatingBaselineMemberLinks()");}
Iterator itr = floatingBaselineMemberList.persistableIterator();
WTArrayList subjectListCollection = new WTArrayList();
while(itr.hasNext()){
Object fbmlObj = itr.next();
if(fbmlObj instanceof FloatingBaselineMember){
FloatingBaselineMember fbml = (FloatingBaselineMember)
fbmlObj;
} }
//Supported API
WTKeyedHashMap associatedActivities =
DeliverableHelper.service.getAssociatedActivities(subjectListCollection);
if(isDebugEnabled){log.debug(" IN Custom handler:
updateFloatingBaselineMemberLinks() - got the assocaited activities with
baseline members");}
WTHashSet activitySet = new WTHashSet();
for(Object obj : associatedActivities.keySet()){
if(obj instanceof ObjectReference){
ObjectReference objectRef = (ObjectReference)obj;
if(associatedActivities.get(objectRef)!=null){
activitySet.addAll((Collection)
associatedActivities.get(objectRef));
}
}
}
WTArrayList actCollection = new WTArrayList();
actCollection.addAll(activitySet);
updateFBMLlogic(actCollection);
if(isDebugEnabled){log.debug(" OUT Custom handler:
updateFloatingBaselineMemberLinks()");}
}
}
Note
Default time delay is 10 seconds. The actions invoked from matrix editor
would be in sync and this property will not be considered for the matrix
editor actions.
Note
Automatic deadline calculation is currently only applicable when the Mark
activity as deliverable option is selected when creating or editing the activity.
Note
When an automatically calculated deadline is set on an As Late As Possible
(ALAP) activity, that deadline can affect the plan deadline. By default, any
changes are automatically rolled up to the plan deadline. To prevent changes
from automatically rolling up, set the following property in wt.properties.
Once set, the plan deadline will only be affected when executing the
Reschedule Plan action:
com.ptc.projectmanagement.plannable.propagateSchedule.OnDeadlineChan
ge.enabled=false
Note
When updating deadlines, Windchill ProjectLink formats time as HH:MM.
Always set seconds and milliseconds as 00:000. If this is not set
appropriately, you might see errors when importing plans from Microsoft
Project that have ALAP activities with deadlines set.
There are two types of deadline calculation algorithms you can create:
You can extend this interface and override certain APIs in order to utilize your
custom algorithm. For example, the following sample code would calculate the
deadline based on the start date of the activity:
try{
WTCollection leafAct = new WTArrayList();
WTCollection leafActivities = new WTArrayList
(activitiesCollection);
leafActivities = CollectionsHelper.manager.refresh
(leafActivities);
PersistenceHelper.manager.save(leafAct);
//After saving the activities, the EPP_CUSTOM_DEADLINE_
CHANGE event
must be thrown so that the subsequent health status
recalculations
and notification emails are triggered.
PlanHelper.service.dispatchMultiEvent
(ProjectManagementEvent.EPP_CUSTOM_DEADLINE_CHANGE,leafAct);
} catch(Exception ae){
ae.printStackTrace();
}
}
}
For example, given the sample handler class above and an internal name of
“org.rnd.Custom_Engineering_Activity”:
<Service context="default" name=
"com.ptc.projectmanagement.plan.EPPDeadlineHandler">
<Option cardinality="singleton" requestor= "null"
selector = "org.rnd.Custom_Engineering_Activity"
serviceClass=
"com.ptc.projectmanagement.plan.CustomDeadlineImplementation"/>
</Service>
Note
The PlanActivity type has following an out-of-the-box handler defined. This
handler has no effect:
<Service context="default" name=
"com.ptc.projectmanagement.plan.EPPDeadlineHandler">
<Option cardinality="singleton" requestor= "null"
selector = "com.ptc.projectmanagement.plan.PlanActivity"
serviceClass=
"com.ptc.projectmanagement.plan.PlanActivityDeadlineHandler"/>
</Service>
You can extend this interface and override certain APIs in order to utilize your
custom algorithm. For example, the following sample code would roll up the
summary activity deadline based on the latest deadline of its child activities:
package com.ptc.projectmanagement.plan.EPPSummaryDeadlineHandler;
public class CustomDeadlineRollUpImplementation
implements EPPSummaryDeadlineHandler {
@Override
public void calculateDeadlineForSummaryActivities
(ArrayList<PlanActivity>
activitiesCollection,
Object event)
throws WTException, WTPropertyVetoException {
try{
WTCollection summaryActivities = new WTArrayList
(activitiesCollection);
summaryActivities = CollectionsHelper.manager.refresh
(summaryActivities);
if (planActivity.isSummary()) {
WTCollection childCollection =
PlannableHelper.service.getAllChildren
(planActivity);
Iterator<PlanActivity> itr =
childCollection.persistableIterator();
} catch(Exception ae){
ae.printStackTrace();
}
}
}
For example, given the sample handler class above and an internal name of
“org.rnd.Custom_Engineering_Activity”:
<Service context="default" name="com.ptc.projectmanagement.
plan.
Note
The PlanActivity type has following an out-of-the-box handler defined. This
handler rolls up the deadline of child activities that are in the critical path:
<Service context="default" name="com.ptc.projectmanagement.plan.
EPPSummaryDeadlineHandler">
<Option cardinality="singleton" requestor= "null"
selector = "com.ptc.projectmanagement.plan.PlanActivity"
serviceClass="com.ptc.projectmanagement.plan.
PlanSummaryActivityDeadlineHandler"/>
</Service>
Note
The following property determines when the status is rolled up from
individual (leaf) activities whose status is calculated through a custom
algorithm:
com.ptc.projectmanagement.plannable.status.rollup.enabled
There are two types of status calculation algorithms you can create:
Individual activity status
For example, your site has a custom “Engineering Activity” and a custom
“Documentation Activity.”
The Engineering Activity is configured so that the status is green when the
deadline is more than 5 weeks away. It is yellow when the deadline is 3 to 5
weeks away. It turns red when the deadline is less than 3 weeks away.
However, the Documentation Activity is configured so that the status is green
when more than 75% of the work has been tracked. It is yellow when 50 to
75% of the work has been tracked. If less than 50% of the work is tracked, the
status is red.
Roll-up status for summary activities
Regardless of whether automatic status calculation is enabled, summary
activity status is always automatically calculated from child activities.
By default, status is rolled up from the least favorable status of critical path
activities. If the summary activity does not have a critical path activity, then it
is calculated from the activities that determine the summary activity end date.
However, you can customize this behavior. For example, your site has a
custom “Development Phase” activity. When used as a summary activity, its
status is calculated from its child activities as follows:
• Green when more than 75% of its child activities are completed.
• Yellow when 50-75% of its child activities are completed.
• Red when less than 50% of its child activities are completed.
To incorporate automatically calculated statuses into your project environment:
1. Create an activity subtype: Set the Status Mode on page 1737.
2. Construct an algorithm for the type of deadline calculation you want to use.
An activity type can use one or both types of algorithms:
Construct a Status Algorithm for Individual Activities on page 1737.
Construct a Status Algorithm for Summary Activities on page 1739.
}
PersistenceHelper.manager.save(leafActivities);
}
}
Note
The PlanActivity type has the following an out-of-the-box handler defined.
This handler has no effect.
<Service context="default" name="com.ptc.projectmanagement.plan.
HealthStatusHandler">
<Option cardinality="singleton" requestor= "null"
selector = "com.ptc.projectmanagement.plan.PlanActivity"
serviceClass="com.ptc.projectmanagement.plan.
PlanActivityHealthStatusHandler"/>
</Service>
You can extend this interface and override certain APIs in order to utilize your
custom algorithm. For example, the following sample code would roll up status
from selected children based on their duration:
package com.ptc.projectmanagement.plan.HealthStatusRollupHandler;
public class SummaryRollupBasedonDurationOfChildren implements
HealthStatusRollupHandler {
@Override
public void rollUpHealthStatus(Plannable plannable, Object
event)
throws WTException, WTPropertyVetoException {
For example, given the sample handler class above and an internal name of
“org.rnd.Custom_Engineering_Activity”:
<Service context="default" name="com.ptc.projectmanagement.
plan.
HealthStatusRollupHandler">
<Option cardinality="singleton" requestor= "null"
selector = "org.rnd.Custom_Engineering_Activity"
serviceClass="com.ptc.projectmanagement.plan.
SummaryRollupBasedonDurationOfChildren"/>
</Service>
4. Run the following command from a Windchill shell:
xconfmanager -p
Note
The PlanActivity type has the following an out-of-the-box handler defined.
This handler rolls up the status from child activities in the critical path:
<Service context="default" name="com.ptc.projectmanagement.plan.
HealthStatusRollupHandler">
<Option cardinality="singleton" requestor= "null"
selector = "com.ptc.projectmanagement.plan.PlanActivity"
serviceClass=
"com.ptc.projectmanagement.plan.PlanHealthStatusRollupHandler"/>
</Service>
Note
When performing an advanced search on action items, all attributes are
available, including those not currently exposed in the user interface.
Note
You can also create or modify the attribute display names through the
associated resource bundle. For information on modifying display names, see
Changing Displayed Text Found in RBINFO Files.
Note
When performing an advanced search on action items, all attributes are
available, including those not currently exposed in the user interface.
Exposed by Default
The following table describes the customizable action item attributes that are
hidden by default:
Hidden by Default
Note
This functionality is applicable to all Windchill Workgroup Managers
integrating with 3rd party CAD tools
Note
PickerSearchAttributeList extends SearchAttributeList;
therefore, the custom class can be used as the
SearchAttributeListDelegate and
PickerSearchAttributeListDelegate.
Note
If extending PickerSearchAttributeList, you may have to set the
filter to avoid NullPointerExceptions. This issue will be addressed in
a future release.
Note
For the default implementation of the object selection page these valid type list
values are query values specified in wt.query.queryResource.
You can remove type IDs from the list of type IDs specified for a type list ID, but
you cannot remove an entry or leave the type list empty.
The <sort preference base name> is the unique string from the
sortPref array in wt.query.SearchAttributeList; it has only to be
unique within the sort names. The sortAttrib is for the attribute name, and the
sortDirect is to indicate ascending or descending. It is false for ascending and
true for descending. The <#> is the number of the sort key, 0 = first key, and so
on. Following are the preferences that are loaded using
wt.load.LoadFromFile and Windchill\loadFiles\
preferences.txt for the All sort:
#All
PrefEntry~allsortAttrib0~number~/wt/query/htmlsearch
PrefEntry~allsortDirect0~false~/wt/query/htmlsearch
PrefEntry~allsortDirect1~true~/wt/query/htmlsearch
In the all-default example, the results are sorted first by the number column and
then by the version column, with the number being in ascending order and the
version in descending order. Currently, the supported number of sort keys is 3,
although theoretically the number of sort keys is limited only by Oracle
performance. No testing beyond 3 keys has been done on the system.
The <sort preference base name> is the unique string from the
sortPref array in wt.query.SearchAttributeList; it has only to be
unique within the sort names. The sortAttrib is for the attribute name, and the
sortDirect is to indicate ascending or descending. It is false for ascending and
true for descending. The <#> is the number of the sort key, 0 = first key, and so
on. Following are the preferences that are loaded using
wt.load.LoadFromFile and Windchill\loadFiles\
preferences.txt for the All sort:
#All
PrefEntry~allsortAttrib0~number~/wt/query/htmlsearch
PrefEntry~allsortDirect0~false~/wt/query/htmlsearch
PrefEntry~allsortAttrib1~versionInfo.identifier.versionId~/wt/
query/htmlsearch
PrefEntry~allsortDirect1~true~/wt/query/htmlsearch
In the all-default example, the results are sorted first by the number column and
then by the version column, with the number being in ascending order and the
version in descending order. Currently, the supported number of sort keys is 3,
although theoretically the number of sort keys is limited only by Oracle
performance. No testing beyond 3 keys has been done on the system.
Note
This functionality is applicable to every Windchill Workgroup Manager that
integrates with 3rd party CAD tools.
Note
Preferences that control naming and numbering of parts created during Auto
Associate are discussed in the “Preferences for Naming and Numbering” help
topic in the Windchill Help Center. Also listed in the table of Auto Associate
preferences in the “Operations Preferences” topic in the Windchill Help
Center section, along with the preferences discussed in the following sections
on Auto Associate.
Note
Even though some methods of the interface are deprecated and no longer used,
the implementation class should have dummy implementations of these
methods in order to compile the class.
Note
The following methods are deprecated and not currently used by the
action; however, you need to provide a dummy implementation of these
methods to compile the class properly.
Note
When you create a customized part, its master must be WTPartMaster or a
subclass of WTPartMaster. The customized part itself must be a WTPart
or a subclass of WTPart.
Note
1. Model items with .prt and .asm extensions are not subject to the following
preferences. If you want to add or remove a model item type that is valid for
association, then you need to explicitly identify all types or sub-types that
should associate.
The preference, Operation ▶ Auto Associate ▶ Disallow Product Structure Links for
CAD Document Types, allows you to specify the CAD document types which
cannot form an Owner association. These are comma-separated values. The
default is <no value>.
The preference, Operation ▶ Auto Associate ▶ Disallow Product Structure Links for
CAD Document Sub-Types, allows you to specify the CAD document sub-types
which cannot form an Owner association. These are comma-separated values. The
default is <no value>.
Note
The allowable values for the preferences, Disallow Product Structure Links by
Document Types and Disallow Product Structure Links by Document Sub-
Types, are listed in the table of Auto Associate preferences in the “Operations
Preferences” section of the Windchill Help Center.
The preference, Operation ▶ Auto Associate ▶ Create Alternate Link On Check In,
when set to "Yes," allows a CAD-document-to-part association of the next
available type (that is, Content) to be created if the matching part found during
Auto Associate already has an Owner association, and allows the checkin to
continue. The default is "No" (no Content association is formed and the check in
fails with an overridable conflict).
import java.lang.String;
import wt.epm.EPMDocument;
import wt.epm.workspaces.EPMWorkspace;
import wt.part.WTPart;
import wt.pom.UniquenessException;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
import wt.vc.VersionControlException;
// import com.ptc.windchill.uwgm.task.autoassociate.
efaultAutoAssociatePartFinderCreator;
import com.ptc.windchill.uwgm.common.autoassociate.
efaultAutoAssociatePartFinderCreator;
System.out.println("Invoked
CustomizedAutoAssociatePartFinderCreator
:: createNewWTPart()");
// get epmdoc
EPMDocument epmDoc = newPartDescriptor.getSourceDoc();
// get workspace
EPMWorkspace ws = newPartDescriptor.getEPMWorkspace();
Note
This functionality is applicable to all Windchill Workgroup Managers
integrating with 3rd party CAD tools
Whenever "Part" is available in the object type list on the Creo Parametric HTML
client object selection page, if "Part" or "All" is selected, both WTPart objects
and custom part objects are listed in the page’s results table.
Automatic part generation is supported through the “Auto Associate Part” action
available on the workspace properties page. To enable automatic custom part
generation when using this command, however, you must either create or modify
your automatic part creator. For more information, see Customizing Auto
Associate on page 1763.
Note
For wt.query.SearchAttributeList, which is the default
configured search attribute list, the type ID is referred to as the query value.
(For more information, see Customizing the HTML Client Object Selection
Page on page 1747).
Note
This functionality is applicable to all Windchill Workgroup Managers
integrating with 3rd party CAD tools
Note
The customized parameters are provided to the client upon download and,
unlike system parameters such as PTC_WM_ITERATION, are not updated in
the Creo Parametric session or the local cache after a Windchill operation (for
example, check in).
<Option cardinality="singleton"
requestor="java.lang.Object"
serviceClass="com.ptc.windchill.uwgm.proesrv.c11n.DefaultModele
dAttributesDelegate"/>
</Service>
Background
The reservation service was originally created to support concurrency control
when editing change management objects (for example, problem reports, change
requests, and change notices).
Change objects do not support the Check Out and Check In actions. As a result, it
was possible for two users to simultaneously initiate the Edit action on the same
object. When this happened, the system would save the updates of whichever user
saved their changes first. The other user would receive an error message and lose
all updates.
1777
With the reservation service implemented, change objects are reserved for a single
user as soon as they launch the Edit action. If another user attempts to edit the
object, they are immediately presented with an error message similar to the
following:
While originally created for change objects, the reservation service was designed
as a general purpose tool that can be used for a variety of other concurrent
modification scenarios.
Limitations
• Objects are reserved for a user, not for a session or a thread. This allows for
simultaneous modification of an object from multiple sessions or threads
running for the same user.
• When using the reservation service, the following enforcements are made:
○ Updates to a reserved object are detected and vetoed by a
PersistenceManagerEvent.UPDATE listener.
○ Deletions of a reserved object are detected and vetoed by a
PersistenceManagerEvent.PRE_DELETE listener.
If this level of enforcement is not appropriate for your application, then the
reservation service enforcement option should be disabled. Instead, you should
create an application-specific service to provide the required enforcement.
Intended Outcome
Prevent unintentional concurrent modifications of a reservable object by two or
more users in a predictable and user-friendly manner.
For example, when a user attempts to edit a problem report that is already being
edited by a user named “Jane Smith,” the following message appears:
When the user clicks OK, the message and edit window closes. The user can try
again later.
Note
Currently the only supported type available is
Modify, but other types might be added in
the future.
For more information, including all supported methods and elements, see the
Windchill Javadoc.
For an example of how the update count client tool is used, see Sample Code:
Reservation Service in Adding the Undo Reservation Action to a Menu on page
1785.
The undoReservation action can be added to the action model of any object
that implements the wt.reservation.Reservable interface. For example,
the change request action model file includes the following undoReservation
entry:
<model name="more change request row actions" menufor=
"wt.change2.WTChangeRequest2">
:
:
<action name="undoReservation" type="reservation"/>
:
<%@include file="/netmarkets/jsp/components/includeWizBean.jspf"%>
<jca:initializeItem operation="${createBean.edit}"/>
<cwiz:initializeChangeWizard changeMode="EDIT"
varianceEffectivity="false" annotationUIContext="change"
changeItemClass="wt.change2.ChangeRequestIfc" />
<jca:wizard helpSelectorKey="change_editChangeRequest"
buttonList="DefaultWizardButtonsWithSubmitPrompt"
formProcessorController=
"com.ptc.windchill.enterprise.change2.forms.controllers.ChangeItemFormPro
cessorController">
<jca:wizardStep action="editAttributesWizStep" type="object" />
<jca:wizardStep action="affectedEndItemsStep" type="change" />
<jca:wizardStep action="affectedDataStep" type="change" />
<jca:wizardStep action="attachments_step" type="attachments" />
<jca:wizardStep action="associatedChangeIssuesStep" type=
"changeRequest" />
<jca:wizardStep action="associatedChangeItemsStep" type="change" />
</jca:wizard>
<rwiz:handleUpdateCount/>
<script language='Javascript'>
change_postLoad();
</script>
Introduction to EXPRESS
EXPRESS is the modeling language used by STEP for defining the information
model for the data exchange. To support STEP-based data exchange using
EXPRESS Data Manager (EDM), Windchill provides EXPRESS schema-specific
definitions for its proprietary information model for data exchange. This model
represented in the form of DTD schema describes the information being
exchanged for various business objects (concepts) represented and managed in
Windchill.
This section details out the various constructs used to generate EXPRESS schema
from DTDs. This lets you see how to convert a Windchill DTD-specific object
model to an EXPRESS-specific object model using the EXPRESS Schema
Generator.
Element Specifications
Elements in the DTD are specified as:
-- <!ELEMENT part (name, (number | ufid)*, item, (sun | mon | tue)
+)>
The same elements are represented in the EXPRESS Schema Representation as:
ENTITY e_part;
name : STRING;
item : e_item;
WHERE
Note
In the above example, the number is prefixed with r_. This is because
number is reserve word in EXPRESS schema language. All attributes from
DTD which match with reserve words in Express language are prefixed with
r_.
attr_value : STRING;
WHERE
check_attr_value: SELF.attr_value IN
['-1','0','1','2','3','4','5','6','7'];
END_ENTITY;
Note
For a sample DTD to EXPRESS entity conversion, see DTD to EXPRESS
Mapping on page 1821.
EXPRESS-X Mapping
The EXPRESS-X based mapping is used to convert a model/file specific from one
EXPRESS Schema into another. In a typical scenario, Windchill business objects
are represented in the Windchill EXPRESS Schema. The same is being converted
Export
This represents the typical flow of an
export operation
1. Collect: Identify what needs to be
exchanged. This step is out of scope
of STEP data exchange.
2. Establish source model confirming
to Windchill Express schema
Windchill Information Exchange
Model using Export Handlers
3. Validate the source model against
the Windchill Express schema
(Optional)
4. Convert to a target model
confirming to a specific application
protocol schema
5. Validate the target model against
the application protocol schema
(Optional)
6. Output to a file.
Note
Reference Type specific attributes are not supported in STEP-based data
exchange.
Apart from the data type based classification; these attributes can be classified into
following attribute types based on the way these are associated with the various
Windchill business objects.
• Typed
• Ad-hoc
• Classification
Note
Only Type Specific business fields are supported.
Note
For more information on attribute types see the Working with the Type and
Attribute Management Utility topic in the Windchill Help Center.
<businessFieldID>
<solution>WINDCHILL</solution>
<namespace>
<category>type</category>
<name>org.rnd.TestPart</name>
</namespace>
<name>accAttr</name>
</businessFieldID>
<datatype>wt.units.FloatingPointWithUnits</datatype>
<datatypeQualifier>QOM=Acceleration,BASE_UNITS=m/s**2</
datatypeQualifier>
<value>23.21|4|m/s**2</value>
<value>12.12|6|m/s**2</value>
<value>33.31|8|m/s**2</value>
<value>56.63|10|m/s**2</value>
</businessField>
Supported Types
Objects types for business fields attributes exchange have to be registered in
stepdex.properties. The property
wt.stepdex.suppported.businessfield.exchange.types must
be set. Comma-separated values need to be provided for the property. You have to
provide the qualified names for each soft type.
For example, if you want to support business field import for object types such as
WCTYPE|wt.part.WTPart|com.ptc.MyPart and
WCTYPE|wt.part.WTPart|com.ptc.computerPart then you have to
make following entries in the stepdex.properties:
wt.stepdex.suppported.businessfield.exchange.types=
com.ptc.MyPart, com.ptc.computerPart
Caution
If any corruption takes place in the working copy of EDM_DB, then it needs
to be replaced with the master copy.
EXPRESS Customizations
This section describes how customization is performed for STEP-based data
Exchange. The following flowchart details the customization steps that need to be
followed to provide mapping for an object. It is recommended that you maintain
protocol specific EDM databases.
Note
Before you start the customization make a backup of the following:
• <WT_HOME>/edm-home/edm_database/<protocol>/user
Note
The <protocol> directory name should be same protocol name used
in stepformat.xml.
• <WT_HOME>/codebase/registry/stepdex
Note
In each case, you need to write new or update existing object-specific
converters. For more information on writing converters, see EXPRESS-X
Mapping on page 1792.
WHEN TRUE;
BEGIN_MAP
LOCAL
--Local variable
END_LOCAL;
ver_act.id :=wt_change.r_number;
END_MAP;
Note
For more information on the EXPRESS Data Manager see EDMassist.
"includes/EportEMPDocument.inn"
"includes/ExportEPMMemberLink.inn"
"includes/EportEPMDescribeLink.inn"
"includes/ExportWTChangeRequest2.inn"
"includes/ExportRepresentation.inn"
"includes/ExportWRPartDescribe.inn"
"includes/ExportWTPartReferenceLink.inn"
"includes/ExportWTPartUsageLink.inn"
"includes/ExportEPMReferenceLink.inn"
"includes/ExportContentItem.inn"
"includes/AP214UnitValueProcessor.inn"
"includes/ExportOrganizationName.inn"
"includes/ExportHandlePropertyDefinition.inn"
"includes/ExportGlobalInstanceFunctions.inn"
"./../ includes/export/ExportBusinessFields.inn"
"./../ includes/StringUtils.inn"
"./../ includes/AggregateUtils.inn"
"./../ includes/DateTimeUtil.inn"
"./../ includes/MesurableUnitsUtil.inn"
END_SOURCE_FILES
*)
FROM (ver_act:aim::versioned_action_request)
WHEN TRUE;
BEGIN_MAP
LOCAL
--Local variables
END_LOCAL
updateRootTag('e_WTChangeRequest2;);
wt_change.r_number := ver_act.id;
END MAP;
4. Register/Include the converter file in the export-specific project file
(AP214TOWNC.xpxprj) as shown in the code below.
(*
*)
SOURCE FILES
"includes/ImportWTPart.inn"
"includes/ImportWTDocument.inn"
"includes/ImportEPMDocument.inn"
"includes/ImportWTChangeRequest2.inn"
"includes/ImportHandlePropertyDefinition.inn"
"includes/ProcessAppliedDocumentReference.inn"
"includes/ImportRepresentation.inn"
"includes/ImportWTPartUsageLink.inn"
"includes/ImportWTPartDescribeLink.inn"
"includes/ImportWTPartReferenceLink.inn"
"includes/ImportEPMMemberLink.inn"
"includes/ImportEPMDescribeLink.inn"
"includes/ImportEPMReferenceLink.inn"
"includes/ImportContentItem.inn"
"includes/ImportGlobalFunctions.inn"
"includes/ImportOrganization.inn"
"includes/ImportUnitUtils.inn"
"./../ includes/StringUtils.inn"
"./../ includes/AggregateUtils.inn"
"./../ includes/DateTimeUtil.inn"
"./../ includes/import/ImportUtil.inn"
"./../ includes/import/ImportWTPartAttributes.inn"
"./../ includes/import/ImportVersionObject.inn"
"./../ includes/import/ImportLifeCycleObject.inn"
"./../ includes/import/ImportBusinessFields.inn"
"./../ includes/import/ImportContentItemAttributes.inn"
"./../ includes/import/ImportWTDocumentAttributes.inn"
"./../ includes/import/ImportWTPartDescribeLink.inn"
"./../ includes/import/ImportRepresentation.inn"
END_SOURCE_FILES
<name>AP214_CUSTOMIZED</name>
<default>false</default>
<specification>
<definition>
<file>stepdex/ap214/schema/10303-214e2-aim-
long.exp
</file>
<schemaName>AUTOMOTIVE_DESIGN</schemaName>
</definition>
</specification>
<configuration>
<exportConfiguration>
<mappingFile>stepdex/ap214/export/WNCTOAP2141.xpxprj</
mappingFile>
<schemaName>WNCTOAP214NEW</schemaName>
<defaultDataExchangeForm>PART_28</defaultDataExchangeForm>
</exportConfiguration>
<importConfiguration>
<mappingFile>stepdex/ap214/importxpx/AP214TOWNC1.xpxprj</
mappingFile>
<schemaName>AP214TOWNCNEW</schemaName>
</importConfiguration>
</configuration>
</protocol>
AP214_CUSTOMIZED.order=80
Note: - Ensure that key matches with the value of <name> element in protocol
entry newly added
3. Configure IXBDocumentDelegate for the new protocol by adding entry
in IXBDocumentDelagetSTEP-service.properties.xconf and
propagating the same.
<Service context="default" name="wt.ixb.publicforapps.
IXDocumentDelegate">
<Option serviceClass="wt.ixb.impl.step.
IxbSTEPDocumentDelegate"
requestor="java.lang.Object"
</Service>
4. Use
IXFormatType.setProtocol(IXFormatTypeProtocolType)
method to set up the protocol.
</Service>
EXPRESS Tools
• EXPRESS Schema Generator on page 1815
• EXPRESS Database Tools on page 1816
○ Create EDM Database on page 1817
○ Load Schema on page 1818
○ Load EXPRESS Schema on page 1819
○ Load Conversion (EXPRESS-X) Schema on page 1819
○ Load Query Schema on page 1819
○ Delete Schema on page 1819
○ Load Model on page 1820
Command Usage
For a given release DTD, following command can be executed to convert DTD to
.exp file (EXPRESS schema file).
java wt.stepdex.schemagenerator.GenerateExpressSchema
<Windchill> <DTD file name> <Output directory>
Where:
• WT_HOME : Windchill Home
• DTD file name: Name of the DTD file. This file should be located in
<Windchill>/loadXMLFiles.
• Output directory: Optional. The default value is the directory where DTD file
name is present.
For example, release specific Windchill EXPRESS schema can be generated using
following command: $> java
wt.stepdex.schemagenerator.GenerateExpressSchema /user/
windchill standardx24.dtd
Command Syntax
$> java
wt.stepdex.expressschemautil.ExpressDbSchemaManager
-createdb [-overwrite] [-dbname (-d) <DBName> -user(-u)
<DBContextLoginName> -password(-p) DBPassword
-location(-l) DBLocation]
Where:
• -createdb : Option to create a new EDM database
• -overwrite : Option to overwrite on an existing database
• DBName : Specify database name
• DBContextLoginName : Specify database context login name
• DBPassword : Specify the database password
• DBLocation : Specify path to database file. This must have the <protocol>
suffix in the directory path. For example: <WT_HOME>/edm-home/edm-
database/AP214 for AP214 specific command execution.
Examples
• Create a new Express DB named “db1” at location “D:/temp/edm”
$> java
wt.stepdex.expressschemautil.ExpressDbSchemaManager
-createdb -d db1 -u superuser -p pwd -l D:\temp\edm
• Overwrite an existing DB named “db1” located at “D:/temp/edm”
Load Schema
STEP-based data exchange requires various schemas to be loaded in EDMDB
prior to actual data exchange process. Based on the nature or behavior, schemas
are divided into following categories.
• Load EXPRESS Schema on page 1819
• Load Conversion (EXPRESS-X) Schema on page 1819
• Load Query Schema on page 1819
These schemas are loaded with the help of EDM EXPRESS Compiler. This tool
has been developed to facilitate the customizers to load various schemas into
EDMDB.
Following command is being used to load the schema into the EDMDB
Command Syntax
$>java
wt.stepdex.expressschemautil.ExpressDbSchemaManager
-loadschema [-overwrite] -type (-t) -e|-x|-q -s
(schemafile) SchemaAbsolutePath [-dbname (-d) <DBName>
-user(-u) <DBContextLoginName> -password(-p) DBPassword
-location(-l) DBLocation]
Where
• -loadSchema: Option for loading a new schema
• -overwrite: Option to overwrite on an existing schema
• -t: Type of the schema. Could be of following 3 options
○ -x: Option to load an EXPRESS-X schema
○ -e Option to load EXPRESS schema
○ -q Option to load Query schema
• SchemaAbsolutePath: Specify absolute path to schema
• DBName : Specify database name
• DBContextLoginName: Specify database context login name
Example
Here is the simple command which loads Windchill express schema into EDMDB
$> java
wt.stepdex.expressschemautil.ExpressDbSchemaManager
-loadschema -t -e -s [WT_HOME]/loadXMLFiles/windchill_
express_schema.exp
Note
If Database details are not present in command, then the tool reads default
database details from the stepdex.properties file.
Delete Schema
Use this command to delete express and express-x conversion schemas from the
EDM database.
Load Model
Various STEP or XML files gets loaded into EDMDB as a Model. This tool will
help you to load model for an existing EXPRESS Schema.
Command Syntax
$> java
wt.stepdex.expressschemautil.ExpressDbSchemaManager
-loadmodel [-overwrite] -modelname(-m) modelName
-stepfile(-f) stepFilePath [-dbname(-d) DBName -user(-u)
DBContextLoginName -password(-p) DBPassword
-dblocation(-l) DBLocation]
Where:
• -loadmodel: Option for loading a model for the given schema
• -overwrite: Option to overwrite on an existing model
• modelname: Name of the model
• stepFilePath: Absolute path of STEP file. Can be either P28 or P21 file
• DBName: Specify database name
• DBContextLoginName: Specify database context login name
• DBPassword: Specify the database password
• DBLocation: Specify path to database
Mapping Information
This section contains the following mapping information:
• DTD to EXPRESS Mapping on page 1821
• IBA Mapping on page 1827
• WTDocument Mapping on page 1831
• EPMDocument Mapping on page 1834
• WTPart Mapping on page 1836
• Representation Mapping on page 1838
• WTPartUsageLink on page 1840
• EPMReferenceLink on page 1842
• EPMMemberLink on page 1843
IBA Mapping
This section contains details out how IBAs are mapped in AP214 standard.
WTDocument Mapping
This section contains details out how WTDocument is mapped in AP214 standard.
versionInfo/iterationId
ObjectID/ufid #18= DESCRIPTIVE_
masterUfid REPRESENTATION_ITEM
('key','value');
CADName
#19= REPRESENTATION('property
authoringApplication value',(#18),#21);
derived #21= REPRESENTATION_CONTEXT
domainName ('','');
folderPath #24= PROPERTY_DEFINITION('key',
$,#1);
lifecycleInfo/lifecycleTemplateName
#25= PROPERTY_DEFINITION_
ifecycleInfo/lifecycleState REPRESENTATION(#24,#19);
versionInfo/versionLevel e.g:
epmDocSubType Key is ‘domainName’
externalTypeId Value is ‘/Default’
WTPart Mapping
Details out how WTPARTs are mapped in AP214 standard
versionInfo/iterationId
ObjectID/ufid #18= DESCRIPTIVE_
masterUfid REPRESENTATION_ITEM('key’,
‘value');
endItem
#19= REPRESENTATION('property
defaultTraceCode value',(#18),#21);
genericType
Representation Mapping
Details out how Representation is mapped in AP214 standard
WTPartUsageLink
Details out how WTPARTUSAGELINKs are mapped in AP214 standard
EPMReferenceLink
Details out how EPMREFERENCELINKs are mapped in AP214 standard
EPMReferenceLink Type AP214 Product Definition
Relationship
EPMReferenceLink #3195= PRODUCT_DEFINITION_
RELATIONSHIP('140','',$,#1,#129);
referenced_by 1= PRODUCT_DEFINITION('Design',
$,#2,#5);
EPMMemberLink
Details out how EPMMEMBERLINKs are mapped in AP214 standard
EPMMemberLink Type AP214 Product Definition
Relationship
EPMMemberLink #185= NEXT_ASSEMBLY_USAGE_
OCCURRENCE('1201','',$,#101,#1,$);
used_by #101= PRODUCT_DEFINITION
('Design',$,#102,#105);
uses #1= PRODUCT_DEFINITION
('Design',$,#2,#5);
occurences/attribute #18= DESCRIPTIVE_
ObjectID/localId REPRESENTATION_ITEM
('key','value');
isAnnotated
#19= REPRESENTATION('property
name value',(#18),#21);
asStoredChildName #21= REPRESENTATION_CONTEXT
depType ('','');
Log Levels
The following table details the possible log levels for validation used by the
wt.stepdex.validation.log.level property.
Log Level Description
AGGREGATE_DATA_TYPE Validate aggregate types
AGGREGATE_SIZE Validate aggregate sizes
AGGREGATE_UNIQUENESS Validate aggregate uniqueness
ARRAY_REQUIRED_ELEMENTS Validate aggregate content: mandatory/
optional membership
DETAILED_OUTPUT Produce detailed validation report
FULL_OUTPUT Produce full validation report
FULL_VALIDATION Validate all constraints.
GLOBAL_RULES Validate global rules
INVERSE_RULES Validate INVERSE rules
LOCAL_RULES Validate domain rules
NO_PRINT_OUTPUT Do not produce any printout
OUTPUT_STEPID Write step id to validation report in
addition to instance id
REQUIRED_ATTRIBUTES Validate mandatory/optional attributes
spec.
STOP_ON_FIRST_ERROR Stop validation of first error
Tools Required
1. A utility to define a source in a target system to identify a system that sends a
data to be imported. The source system is the one for which different mapping
rules are getting established. This utility creates
CollaborationSourceInfor, Repository and
PreferenceClient objects in the target system.
2. An import utility to populate PreferenceDefinition and
MultiValuePreference instances.
3. Optional. A Mapping Converter Utility provided as a reference
implementation (which can be custom created for specific business) that
converts mapping data in CSV format (usually populated using MS Excel like
</Mapping>
This is an example configuration for handling the lifecycle attribute mapping.
<Mapping preferenceDefinition="R_lifecycle" separator=";"
mappingProcessor="wt.ixb.publicforapps.extendedmapping.
processor.MultiTagMappingProcessor">
<Tag value="lifecycleInfo/lifecycleTemplateName"/>
<!-this is the element that is mapped -!>
<Tag value="lifecycleInfo/lifecycleState"/>
<!-This is another element that is mapped -!>
</Mapping>
Note
A sample file resides in the system at the following location: ..\IX_LOAD\
prog_examples\Mappings\src\
IXMappingConfiguration.xml
You are required to populate all the Mapping elements from this file into
IXMappingConfiguration.xml to be able to use the Mapping Converter
utility.
As seen in the Mapping structure, multiple Mappings can be defined. Each
Mapping element is associated with one preferenceDefinition and one
mappingProcessor. An optional applicableXApplications attribute
can be provided to limit the Mapping configuration only to those IX applications.
applicableXApplications is a comma separated list of applicable
applications. If not specified, the Mapping is applicable to all applications.
Each Mapping element can have one or multiple tags defined under it. Tags can be
of type condition (defined by condition=”true” attribute) or Mappable type
(non-condition). These mappable tags would be implicitly have "condition=
false". The tags of type condition can specify an attribute “multi=true” to
define that the specific element referred to by the value attribute can have multiple
instances and each instance would be picked up to evaluate the condition.
Only mappable Tags are considered for returning the mapped value. One tag of
Mappable type can have only one applicable mappingProcessor and one
preferenceDefinition associated with it. In case there are multiple
Mapping definition for the same Tag, the first applicable Mapping definition in
this config file would be picked up for a mappable tag. Multiple tags of type
condition for a mapping will be AND condition.
Note
A sample file resides in the system at the following location: ..\IX_
LOAD\prog_examples\Mappings\src\mappings-pref.xml
<clientName>
536416322-1456322554305-2141932519-203-136-220-10
</clientName>
</LinkPreferenceClientDefinition>
2. You can populate all the mappings in the CSV format as in the sample. And,
then a Mapping converter utility as follows to generate a Preference Definition
file that can be imported.
Note
A sample file resides in the system at the following location: ..\IX_
LOAD\prog_examples\Mappings\src\mappings.csv
windchill
wt.ixb.publicforapps.extendedmapping.tools.Metadat
aMappingConverter -csvtoxml "e:\ptc\mapping-test\
mappings.csv" null mappings-pref true
mappings-pref is the output XML file name to be latter imported.
And, here is the command to import the preference definitions into the system.
windchill wt.preference.ImportPreferences
-importfile=e:\ptc\mapping-test\mappings-pref.xml
-overwriteValueConflicts -user=wcadmin -password=
wcadmin
Note
Find more on this utility using the ‘-usage’ option.
windchill wt.preference.ImportPreferences -usage
Note
A sample file resides in the system at the following location: ..\IX_LOAD\
prog_examples\Mappings\src\mappings-instances.xml
Note
A sample file resides in the system at the following location: ..\IX_LOAD\
prog_examples\Mappings\src\delete_preferenceDef_
NmLoader.xml
Note
Preserve the CSV data for subsequent updates. As there is no easy way to
extract information from the system into CSV format
windchill-version=11.0.10.00.235
standard-dtd=standardX26.dtd
format=STEP
multiple=true
<PreferenceDefinition>
<name>R_folderPath</name>
<visibility>HIDDEN</visibility>
<categoryName>FederationMapping</categoryName>
<displayName>R_folderPath</displayName>
<description>R_folderPath</description>
<fullDescription>R_folderPath</fullDescription>
<defaultValue></defaultValue>
<handler>com.ptc.windchill.enterprise.preference.handler.
MultiValueMapPreferenceHandler:</handler>
<defaultComments></defaultComments>
<clientOverride>false</clientOverride>
</PreferenceDefinition>
<LinkPreferenceClientDefinition>
<name>R_folderPath</name>
<clientName>536416322-1456322554305-2141932519-203-136-220-10</
clientName>
</LinkPreferenceClientDefinition>
Logging
You can use the following log4j flags to enable the logging in the Method
Server.
• log4j.logger.wt.ixb.publicforapps.extendedmapping
=DEBUG or TRACE
• log4j.logger.wt.ixb.publicforapps.extendedmapping
=DEBUG or TRACE
The DEBUG level would identify the exact mapping rule that has come into effect
while the TRACE level would provide you additional details on what different
candidate mapping rules were evaluated.
Class Diagram
Note
Please refer to the class diagram and data structure table in the previous
section for reference.
For Mapping definition with multiple Tags with conditions and regular
expressions in IXMappingConfiguration.xml, matching mapping can be
more than one. In those cases, OOTB implementation uses the logic to return the
match with maximum conditions met (there can be some mappings in multiple
matches without all conditions provided in the mapping). Also in case of multiple
regular expressions defined in the Mapping matches the source object values, the
natural sort order as implemented by java.util.TreeMap is used and the
first match is used for mapping value.
The above behavior to pick the matching key can be customized.
Extend
wt.ixb.publicforapps.extendedmapping.mapper.MultiTagCom
plexMapper class and override getBestMatchKey method as per the below
details.
/** Get the best matching key to be used to get the mapped values
* OOTB implementation returns the first matching key.
* This api can be overridden to return any other matching key
from
* @param matchingKeys
* All matching keys satisfying the Mapping conditions
* @return The first key out of all matching keys
*/
Tips
• The following variables can be used in required_attributes:
• {ROOT} : Use the root object of this element
• {UUID} : Create a random UUID
• {KEY} : Use the name of the current attribute
• {VALUE} : Use the string representation of the current attribute’s value
Alias Mapping
Defines an alias for the mapping path which can be used in mapped name and
required attributes in element mapping section. This will reduce duplicated
mappings. This will be only a relative path.
Tips
Use the following pattern to define value attribute:
{ROOT}/usedBy/ObjectReference/ufid, this means to get the value of
attribute named usedBy/ObjectReference/ufid from the current element.
String Mapping
Part 21 Representation
#1= PART($,$,$,$,$,$,(#2));
#2= PARTVERSION($,$,$,$,$);
#12= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('localId'),$,$,
CHARACTERSTRING('wt.epm.EPMDocument:129174'));
#13= PROPERTYVALUEASSIGNMENT($,$,$,$,(#12),#2,$);
Part 21 Representation
#8= ORGANIZATION(IDENTIFIERSTRING('/NULL'),#9,$,$,$);
#9= LOCALIZEDSTRING($,'Demo Organization');
#95= VIEWCONTEXT(CHARACTERSTRING('part definition'),PROXYSTRING(
'mechanical design'),PROXYSTRING('design'));
#133= PARTVIEW($,$,$,$,$,#95,$);
#136= PROPERTYVALUEASSIGNMENT($,$,$,$,(#98),#133,$);
Part 21 Representation
#8= ORGANIZATION(IDENTIFIERSTRING('/NULL'),#9,$,$,$);
Part 21 Representation
#1= PART($,$,$,$,$,$,(#2));#2= PARTVERSION(#5,$,$,$,$);
#3= ORGANIZATION(IDENTIFIERSTRING('Demo Organization'),#4,$,$,$);
#4= LOCALIZEDSTRING($,'Demo Organization');
#5= IDENTIFIER('1.1',$,CLASSSTRING('identification information'),
#3);
Part 21 Representation
#11= ORGANIZATION(IDENTIFIERSTRING('Demo Organization'),#12,$,$,
$);
#12= LOCALIZEDSTRING($,'Demo Organization');
#27= IDENTIFIER('A.1',$,CLASSSTRING('identification information'),
#11);
Mapping table
Windchill BOM
e_EPMDocument Part. (for master)
PartVersion and PartView. (for
iteration)
Part.versions[] =
PartVersion
PartVersion.views[] =
PartView
PartView.initialContext =
ViewContext
ViewContext.description =
‘part definition’
ViewContext.applicationDo
main=’digital mock-up’
ViewContext.lifeCycle
Stage=’design’
r_number Part.id
Name LocalizedString.text
Part.name = LocalizedString
Version PartVersion.id = Identifier
Note
For more information see Identifier
Mapping Table on page 1895.
lifecycleState Approval.status
externalTypeId If object as Custom or Soft type then
Note Part.ClassifiedAs.Classifi
cation++Class
If the object is not Custom Type or
Soft Type then externalTypeId Class.id = externalTypeId
is exported as PropertyValue. Class.definedIn
=ExternalClassSystem
ExternalClassSystem.id=
’customized part types’ as
Identifier
Note
For more information see Identifier
Mapping Table on page 1895.
Attributes For more information seeModel
[ObjectID.localId, Attributes Mapping on page 1890.
ObjectID.ufid,
objectContainerPath,
ownerApplication,
authoringApplication,
masterUfid,
masterExternalTypeId,
CADName,
epmDocType,
defaultUnit,
collapsible,
genericType,
lengthScale,
domainName,
folderPath,
versionInfo.versionLevel,
versionInfo.series,
versionInfo.versionPosi
tion,
versionInfo.iterationSer
ies,
versionInfo.iterationPosi
tion,
lifecycleTemplateName,ex
ternalTypeId]
Organization For more information see Organization
Mapping Table on page 1894.
Mapping Table
WNC BOM
e_WTDocument Document. (for master)
DocumentVersion and
DocumentDefinition. (for
iteration)
Document.versions[] =
DocumentVersion
ApprovalAssignment.assigne
dApproval = Approval
ApprovalAssignment.as
signedTo=[DocumentVersion]
. (for lifecycle)
DocumentVersion.views[] =
DocumentDefinition
ViewContext.description =
‘part definition’
ViewContext.applicationDo
main=’mechanical design’
ViewContext.lifeCycle
Stage=’design’
ViewContext.lifeCycle
Stage=’InWork’
r_number Document.id
Name LocalizedString.text
Document.name =
LocalizedString
Version DocumentVersion.id =
Identifier
Note
For more information see Identifier
Mapping Table on page 1895.
lifecycleState Approval.status
externalTypeId If object as Custom or Soft type then
Document.ClassifiedAs.Clas
sification++Class
FederationInfo.additional
PersistInfo.master.local
Id,
FederationInfo.additional
PersistInfo.master.update
Count,
FederationInfo.repositor
yInfo.lastKnownRepository,
FederationInfo.masterRepo
sitoryInfo.owningReposito
ry,
FederationInfo.masterRepo
sitoryInfo.masterLastKnown
Repository,
ObjectID.ufid,objectContai
nerPath,
masterUfId,docType,
docTitle,
department,
domainName,
folderPath,
versionInfo.versionLevel,
versionInfo.series,
Part 21 Representation
#1= DOCUMENT(#38,#39,$,$,(#6),$,(#2));
#2= DOCUMENTVERSION(#30,$,$,$,(#4));
#4= DOCUMENTDEFINITION($,$,$,$,$,$,$,$,$);
#8= APPROVALASSIGNMENT($,$,$,#31,(#2));
#13= VIEWCONTEXT(CHARACTERSTRING('part definition'),PROXYSTRING(
'mechanical design'),PROXYSTRING('design'));
#30= IDENTIFIER('A.1',$,CLASSSTRING('identification information'),
#11);
#31= APPROVAL($,$,$,$,$,$,CLASSSTRING('INWORK'),$);
#38= IDENTIFIER('0000000001',$,CLASSSTRING('identification
information'),#11);
#39= LOCALIZEDSTRING($,'submissionDocument');
Mapping Table
WNC BOM
e_WTPart Part. (for master)
PartVersion and PartView. (for
iteration)
Part.versions[] =
PartVersion
PartVersion.views[] =
PartView
PartView.initialContext =
ViewContext
OR
AssemblyDefinition.initial
Context = ViewContext
(PartView is used if the WTPart has
no children. AssemblyDefinition
is used if the WTPart does have
children).
ViewContext.description =
‘part definition’
ViewContext.applicationDo
main=’mechanical design
ViewContext.lifeCycle
Stage=’design’
r_number Part.id
name LocalizedString.text
Part.name = LocalizedString
expressionData Condition entity representing this
(gets populated for advance assigned expression data
ConditionalConfiguration.condi
expression on the part)
tion=condition
EffectivityAssignment.assignedEf
fectivity=
ConditionalConfiguration
EffectivityAssignment.assigned
To=partVersion
EffectivityAssignment.role=
’required’
EffectivityAssignment.effectivi
ObjectID.ufid,
ObjectID.FederationInfo.ad
ditionalPersistInfo.mas
ter.localId,
ObjectID.FederationInfo.re
positoryInfo.lastKnownRepo
sitory,
ObjectID.FederationInfo.
masterRepositoryInfo.ow
ningRepository,
ObjectID.FederationInfo.
masterRepositoryInfo.last
KnownRepository,
objectContainerPath,
masterUfid,
name,
Mapping Table
WNC BOM
e_WTPartUsageLink NextAssemblyViewUsage.rela
tionType=’next assembly view’
Attributes; localId, ufid, For more information see Model
externalTypeId, traceCode, Attributes Mapping on page 1890.
lineNumber, With
cadSynchronized, PropertyDefinitionSelect as
componentId NextAssemblyViewUsage
expressionData Condition entity representing this
(gets populated for advance assigned expression data
ConditionalConfiguration.condi
expression on the usage)
tion=condition
EffectivityAssignment.assignedEf
fectivity=
ConditionalConfiguration
EffectivityAssignment.assigned
To=NextAssemblyViewUsage
EffectivityAssignment.role=
’required’
EffectivityAssignment.effectivi
tyIndication=TRUE
For more information, see
expressionData Mapping.
Part 21 Representation
#1= ASSEMBLYDEFINITION($,$,$,$,$,#11,$,$);
#11= VIEWCONTEXT(CHARACTERSTRING('part definition'),
PROXYSTRING('mechanical design'),
PROXYSTRING('design'));
#51= ASSEMBLYDEFINITION($,$,$,$,$,#11,$,$);
#228= NEXTASSEMBLYVIEWUSAGE($,$,$,*,#51,#1,$,IDENTIFIERSTRING('A1,
A2'),#230);
#229= PROPERTYVALUEASSIGNMENT($,$,$,$,(#231,#233,#234,#235,#236,
#237),#228,$);
#230= NUMERICALVALUE($,$,PROPERTYDEFINITIONSTRING('quantity'),$,$,
$,#220,2.,$);
#231= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('localId'),$,$,
CHARACTERSTRING
('wt.part.WTPartUsageLink:160359'));
#233= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('ufid'),$,$,
CHARACTERSTRING
('wt.part.WTPartUsageLink:160359|789177195-1452009825602-
2048102341-88-244-152-10|
esdcsv-ccv11c.ptcnet.ptc.com'));
#234= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('externalType'),$,$
,CHARACTERSTRING
('WCTYPE|wt.part.WTPartUsageLink'));
#235= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('traceCode'),$,$,
CHARACTERSTRING('0'));
#236= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('cadSynchronized'),
$,$,
CHARACTERSTRING('no'));
EPMMemberLink
Mapping Table
WNC BOM
e_EPMMemberLink (that has NextAssemblyOccurrenceUsa
transform matrix, with ge.relationType=’next
quantityAmount equal to ‘1’ and assembly
quantityUnit equal to ‘ea’) view’NextAssemblyOccurren
ceUsage.related=
SingleOccurrence
e_EPMMemberLink (that doesn’t ViewOccurrenceRelationshi
have transform matrix, or p.relationType=’next
quantityUnit not equal to ‘ea’, or assembly
quantityAmount not equal to ‘1’) view’ViewOccurrenceRelation
ship.related=
QuantifiedOccurrence
Attributes; localId, ufid, Model Attributes Mapping on page
externalTypeId, depType, 1890
asStoredChildName, With
isRequired, uniqueLinkId, PropertyDefinitionSelect as
uniqueNDId, isSuppressed, NextAssemblyOccurrenceUs
isFixed, isAnnotated, age if e_EPMMemberLink has
identifier, quantityAmount, transform, otherwise
quantityUnit, isPlaced, ViewOccurrenceRelationship.
hasTransform, compNumber,
compRevNumber,
Part 21 Representation
#204= NEXTASSEMBLYOCCURRENCEUSAGE($,$,$,*,#1,#227,#229);
#205= PROPERTYVALUEASSIGNMENT($,$,$,$,(#206,#208,#209,#210,
#211,#212,#213,#214,#215,#216,#217,#218,#219,#220,
#221,#222,#223,#224,#225,#226),#204,$);
#206= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('localId'),$,$,
CHARACTERSTRING
('wt.epm.structure.EPMMemberLink:192332'));
#208= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('ufid'),$,$,
CHARACTERSTRING(
'wt.epm.structure.EPMMemberLink:192332|789177195-1452009825602-
2048102341-88
-244-152-10
|esdcsv-ccv11c.ptcnet.ptc.com'));
#209= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('externalTypeId'),
$,$,
CHARACTERSTRING(
'WCTYPE|wt.epm.structure.EPMMemberLink|
com.ptc.ptcnet.DefaultEPMMemberLink'));
OR
WTPartDescribeLink
Mapping Table
WNC AP242
e_WTPartDescribeLink DocumentAssignment
describedBy documentAssignment.as
signedDocument :=
documentVersion (i.e.
DocumentDefinition);
describes documentAssignment.as
signedTo ++
assemblyDefinition (i.e.
PartView);
Part 21 Representation
#62= DIGITALDOCUMENTDEFINITION($,$,$,$,$,$,$,$,$,(#89,#105,#119));
WTPartReferenceLink
Mapping Table
WNC AP242
e_WTPartReferenceLink DocumentAssignment
referencedBy documentAssignment.as
signedTo ++
assemblyDefinition (i.e.
PartView);
references documentAssignment.as
signedDocument :=
documentVersion (i.e.
DocumentDefinition);
Part 21 Representation
#358= PARTVIEW($,$,$,$,$,#8,$);
#419= DOCUMENTASSIGNMENT($,$,$,CLASSSTRING('description'),$,
(#358),$);
#420= PROPERTYVALUEASSIGNMENT($,$,$,$,(#426,#428),#419,$);
#422= DATETIMEASSIGNMENT($,$,$,CLASSSTRING('creation'),$,(#419));
#424= DATETIMEASSIGNMENT($,$,$,CLASSSTRING('update'),$,(#419));
#426= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('localId'),$,$,
CHARACTERSTRING('wt.part.WTPartReferenceLink:116155'));
#428= STRINGVALUE($,$,PROPERTYDEFINITIONSTRING('externalTypeId'),
$,$,
CHARACTERSTRING('WCTYPE|wt.part.WTPartReferenceLink'));
Mapping Table
WNC AP242
e_businessField Business Fields String Mapping on
Boolean/String/URL values page 1891
Where attribute_name =
businessField.businessFiel
dID.name
attribute_value =
businessField.r_value
Date Timestamp DATETIMEASSIGNMENT
DATETIMEASSIGNMENT.id =
businessField.businessFiel
dID.name
CLASS.id = ‘user defined
attribute’
DATETIMEASSIGNMENT.role =
class
DATETIMEASSIGNMENT.as
signedDate =
businessField/Value
The date is converted to ISO standard
format. Refer to mapping information.
YYYY-MM-DDTHH:MM:SS
DATETIMEASSIGNMENT.as
signedTo =
PropertyAssignmentSelect
Integer Value For more information seeBusiness
Fields String Mapping on page 1891.
Where attribute_name =
businessField.businessFiel
dID.name
attribute_value =
businessField.r_value
Mapping Table
As in the incoming data from non-WC system (w.r.t above snippet), there is no
means by which localId/ufid can be extracted. So the general strategy for
generation localId and ufid for associations would be as described in the
table below.
Part 21 Representation
#3321= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_OCR'),PROXYSTRING
('FROZEN'));
#3326= PARTVIEW($,$,$,$,$,#3321,$);
#3361= PARTVERSION(IDENTIFIERSTRING('001'),CHARACTERSTRING(''),$,
$,(#3326));
#3404= PART(IDENTIFIERSTRING('OCR0847312'),TRANSLATEDSTRINGSET
((#3406,#3408))
,$,$,(#3325,#280),$,(#3361));
#3408= LOCALIZEDSTRING($,'VIS RLX M50,80-12 AUTOTAR SA1ND');
#3414= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_IND'),PROXYSTRING
('FROZEN'));
#3421= PARTVIEW($,$,$,$,$,#3414,$);
#3456= PARTVERSION(IDENTIFIERSTRING('002'),CHARACTERSTRING(''),$,
$,(#3421));
#3499= PART(IDENTIFIERSTRING('7703026050--A'),TRANSLATEDSTRINGSET
((#3501,#3503))
,$,$,(#3420,#280),$,(#3456));
#3503= LOCALIZEDSTRING($,'VIS RLX M50,80-12 AUTOTAR SA1ND');
Mapping Table
AP242 Windchill Notes
NextAssemblyOccur e_ Only one instance per a
renceUsage(…); WTPartUsage distinct pair of parent/
Link(…); child (relating/related) is
ViewOccurenceRela e_ created.
tionship(…); WTPartUsage
Link(…);
For more information see e_
LocalId and Ufid WTPartUsageLin
Generation for k.ObjectID.local
Associations on page Id, e_
1919. WTPartUsageLin
k.ObjectID.ufid
Part 21 Representation
#384= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_CMP'),PROXYSTRING
('FROZEN'));
#386= PARTVIEW($,$,$,$,$,#384,$);
#869= NEXTASSEMBLYOCCURRENCEUSAGE(IDENTIFIERSTRING('2407966'),
CHARACTERSTRING(''),$,*,#386,#892,#893);
#892= SINGLEOCCURRENCE(IDENTIFIERSTRING('1'),$,$,$,#5306);
#893= CARTESIANTRANSFORMATION($,$,((1.,0.,0.),(0.,1.,0.),
(0.,0.,1.)),$,
(0.,0.,0.));
#3268= PARTVERSION(IDENTIFIERSTRING('001'),CHARACTERSTRING(''),$,
$,(#386));
#3311= PART(IDENTIFIERSTRING('CMP0847328'),TRANSLATEDSTRINGSET
((#3313,#3315)
),$,$,(#385,#280),$,(#3268));
#5305= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_OCR'),PROXYSTRING
('FROZEN'));
#5306= PARTVIEW($,$,$,$,$,#5305,$);
#5341= PARTVERSION(IDENTIFIERSTRING('001'),CHARACTERSTRING(''),$,
$,(#5306));
#5384= PART(IDENTIFIERSTRING('OCR0847327'),TRANSLATEDSTRINGSET
((#5386,#5388))
EPMMemberLink
Mapping Table
AP242 Windchill
NextAssemblyOccurren e_EPMMemberLink(…);
ceUsage(…);
ViewOccurenceRelation e_WTPartUsageLink(…);
ship(…);
For more information see LocalId e_EPMMemberLink.ObjectID.localId, e_
and Ufid Generation for EPMMemberLink.ObjectID.ufid
Associations on page 1919.
'WCTYPE|wt.epm.structur e_EPMMemberLink.externalTypeId
e.EPMMemberLink'
NextAssemblyOccurrenceU e_EPMMemberLink.quantityUnit
sage.related = (If it is SingleOccurence, quantity is 1 and unit is
SingleOccurrence (…); “ea”)
or (If QuantifieidOccurence, quantity and unit is
ViewoccurrenceRelation picked up from that entity)
ship.related=
QuantifiedOccur
rence(…);
QuantifiedOccurrence.
quantity =
NumericalValue(…);
NumericalValue.unit
=Unit(…);
Unit.name
Part 21 Representation
#384= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_CMP'),PROXYSTRING
('FROZEN'));
#386= PARTVIEW($,$,$,$,$,#384,$);
#869= NEXTASSEMBLYOCCURRENCEUSAGE(IDENTIFIERSTRING('2407966'),
CHARACTERSTRING
(''),$,*,#386,#892,#893);
#892= SINGLEOCCURRENCE(IDENTIFIERSTRING('1'),$,$,$,#5306);
#893= CARTESIANTRANSFORMATION($,$,((1.,0.,0.),(0.,1.,0.),
(0.,0.,1.)),$,
(0.,0.,0.));
#3268= PARTVERSION(IDENTIFIERSTRING('001'),CHARACTERSTRING(''),$,
$,(#386));
#3311= PART(IDENTIFIERSTRING('CMP0847328'),TRANSLATEDSTRINGSET
((#3313,#3315)
),$,$,(#385,#280),$,(#3268));
#5305= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_OCR'),PROXYSTRING
('FROZEN'));
#5306= PARTVIEW($,$,$,$,$,#5305,$);
#5341= PARTVERSION(IDENTIFIERSTRING('001'),CHARACTERSTRING(''),$,
$,(#5306));
#5384= PART(IDENTIFIERSTRING('OCR0847327'),TRANSLATEDSTRINGSET
((#5386,#5388))
,$,$,(#3325,#280),$,(#5341));
Mapping Table
AP242 Windchill
DocumentAssignment (…); e_WTPartDescribeLink (…);
When the DocumentAssignment.
role is present in the
describeLinkRolesList from
Generic.inn.
For example – For Windchill to
Windchill export/import default role is
‘description’.
For more information see LocalId and e_
Ufid Generation for Associations on WTPartDescribeLink.ObjectI
page 1919. D.localId, e_
WTPartDescribeLink.ObjectI
D.ufid
'WCTYPE|wt.part.WTPartDe e_
scribeLink' WTPartDescribeLink.exter
nalTypeId
DocumentAssignment.as e_
signedDocument = DOCUMENT WTPartDescribeLink.descri
(…); bedBy
One can navigate from a Document to
the DocumentVersion using the
INVERSE attributes on the Document
entity.
DocumentAssignment.as e_
signedTo = PartView(…); WTPartDescribeLink.de
scribes
One can navigate from a PartView to
the Part using the INVERSE
attributes on the PartView and
PartVersion entities.
Part 21 Representation
#31696= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_CST'),PROXYSTRING
('FROZEN'));
#31697= PARTVIEW($,$,$,$,#31765,#31696,$);
#31700= DOCUMENTASSIGNMENT(IDENTIFIERSTRING('G000812460_001'),
CHARACTERSTRING(''),$,CLASSSTRING('describeLinkRole'),#31710,
(#31697),$);
#31710= DOCUMENT(IDENTIFIERSTRING('G000812460'),CHARACTERSTRING
('G000286254')
WTPartReferenceLink
Mapping Table
AP242 Windchill
DocumentAssignment (…); e_WTPartReferenceLink (…);
When the
DocumentAssignment.role is
present in the
referenceLinkRolesList from
Generic.inn.
For example – For Windchillto
Windchill export/import default role is
‘description’.
For more information see LocalId and e_
Ufid Generation for Associations on WTPartReferenceLink.Objec
page 1919. tID.localId, e_
WTPartReferenceLink.Objec
tID.ufid
'WCTYPE|wt.part.WTPartRe e_
ferenceLink' WTPartReferenceLink.exter
nalTypeId
DocumentAssignment.as e_
signedDocument = DOCUMENT WTPartReferenceLink.refer
(…); ences
One can navigate from a Document to
the DocumentVersion using the
INVERSE attributes on the Document
entity.
DocumentAssignment.as e_
signedTo = PartView(…); WTPartReferenceLink.refer
encedBy
One can navigate from a PartView to
the Part using the INVERSE
attributes on the PartView and
PartVersion entities.
WTDocument
Mapping Table
AP242 Windchill
DocumentDefinition (…); OR e_WTDocument (…);
DigitalDocumentDefinition
(…);
It is processed when the
Document.documentTypes is
present in the
wcDocumentTypesList or
nonWCDoumentTypesList from
Generic.inn.
For more information see LocalId and e_
Ufid Generation for Associations on WTDocument.ObjectID.local
page 1919. Id, e_
WTDocument.ObjectID.ufid
For more information see e_
ExternalTypeId in LocalId and Ufid WTDocument.externalTypeId
Generation for Associations on page
1919.
Part 21 Representation
#29866= DIGITALDOCUMENTDEFINITION(IDENTIFIERSTRING('2'),$,$,$,
#29883,$,$,$,$,(#217));
#29869= DOCUMENTVERSION(IDENTIFIERSTRING('002'),$,$,$,(#29866));
#29791= DOCUMENT(IDENTIFIERSTRING('G000538031'),CHARACTERSTRING
('G000286254'),CHARACTERSTRING('PLAQUE RENFORT FIX DOSSIER AR D'),
$,
(#3675),$,(#29869));
#3675= CLASS(IDENTIFIERSTRING('3DR'),$,$,$);
Mapping Table
AP242 Windchill
PartView (…); OR e_WTPart (…);
AssemblyDefinition (…);
It is processed when the
PartView.initialContext is
present in the
wtPartViewContextsList from
Generic.inn.
For more information see LocalId and e_WTPart.ObjectID.localId,
Ufid Generation for Associations on e_WTPart.ObjectID.ufid
page 1919.
For more information see e_WTPart.externalTypeId
ExternalTypeId in LocalId and Ufid
Generation for Associations on page
1919.
Part 21 Representation
#3600= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_CST'),PROXYSTRING
('FROZEN'));
#3603= PARTVIEW($,$,$,$,#3671,#3600,$);
#3620= PARTVERSION(IDENTIFIERSTRING('001'),CHARACTERSTRING(''),$,
$,(#3603));
#3663= PART(IDENTIFIERSTRING('G000277428'),TRANSLATEDSTRINGSET
((#3665,#3667)),$,$,(#3602,#280),$,(#3620));
#3602= CLASS(IDENTIFIERSTRING('CST'),$,$,$);
#280= CLASS(IDENTIFIERSTRING('piece part'),$,$,$);
Mapping Table
AP242 Windchill
PartView (…); OR e_EPMDocument (…);
AssemblyDefinition (…);
It is processed when the
PartView.initialContext is
present in the
epmDocumentViewContexts
List from Generic.inn.
For more information see LocalId and e_
Ufid Generation for Associations on EPMDocument.ObjectID.local
page 1919. Id, e_
EPMDocument.ObjectID.ufid
For more information see e_
ExternalTypeId in LocalId and Ufid EPMDocument.externalTypeId
Generation for Associations on page
1919.
Part 21 Representation
#3600= VIEWCONTEXT($,PROXYSTRING('VPLM_RN_PDT_CST'),PROXYSTRING
('FROZEN'));
#3603= PARTVIEW($,$,$,$,#3671,#3600,$);
#3620= PARTVERSION(IDENTIFIERSTRING('001'),CHARACTERSTRING(''),$,
$,
(#3603));
#3663= PART(IDENTIFIERSTRING('G000277428'),TRANSLATEDSTRINGSET
((#3665,#3667)),$,$,(#3602,#280),$,(#3620));
#3602= CLASS(IDENTIFIERSTRING('CST'),$,$,$);
#280= CLASS(IDENTIFIERSTRING('piece part'),$,$,$);
Mapping Table
AP242 Windchill
DigitalDocumentDefinition. e_contentItem.role
viewOf.versionOf.document
Types[]
If content role cannot be found using
value above, then try using-
DigitalDocumentDefinition.
documentFormat
If content role cannot be found using
value above, then try using-
DigitalDocumentDefinition.
files[].Format.dataFormat
If content role cannot be found using
value above, then try using-
DigitalDocumentDefinition.
files[].locations[].id
Values found in the above entities are
matched against the values found in the
contentRoleToDocumentType
String,
contentRoleToDataFormat
String and
contentRoleToFileExtension
String variables in “Generic.inn” to
find a content role.
Choice
PART 21 Representation:
#361= SPECIFICATION(#362,CHARACTERSTRING('choice 3.1'),
CHARACTERSTRING(((null))'),IDENTIFIERSTRING('A.1'),$,#325,.F.);
#362= IDENTIFIER('00041',$,#58,#13);
#872= SPECIFICATIONASSIGNMENT($,$,#634,#207);
PART 21 representation
#978= SPECIFICATIONCONDITIONASSIGNMENT(CHARACTERSTRING('((null))')
,$,CLASSSTRING('validity'),#979,#207);
PART 21 Representation
#1052= SPECIFICATIONINCLUSION(#1054,CHARACTERSTRING(' ((null))'),
$,#600,#1092);
#1053= SPECIFICATIONINCLUSIONASSIGNMENT($,$,#1052,#207);
#1092= ANDCONDITION($,$,$,*,(#943,#908,#1094),$);
#1094= NOTEQUALSCONDITION($,$,$,*,(#929,#887,#936),$);
PART 21 Representation
#1016= SPECIFICATIONINCLUSION(#1018,CHARACTERSTRING(' ((null))'),
$,#770,#1090);
#1017= SPECIFICATIONINCLUSIONASSIGNMENT($,$,#1016,#207);
#1018= IDENTIFIER('I-00043',$,#58,#13);
#1090= ANDCONDITION($,$,$,*,(#838,#736),$);
PART 21 : Representation
#325= SPECIFICATIONCATEGORY(#327,CHARACTERSTRING('option 3'),$,.
T.);
#361= SPECIFICATION(#362,CHARACTERSTRING('choice 3.1'),
CHARACTERSTRING(((null))'),IDENTIFIERSTRING('A.1'),$,#325,.F.);
OptionSet
PART 21 Representation
#207= PRODUCTCLASS(#208,$,CHARACTERSTRING(' ((null))')
,$,$,$,IDENTIFIERSTRING('A.7'),$);
#208= IDENTIFIER('Option Set 1',$,#58,#13);
OptionSetMemberLink
Get startDate
DataValidityEffectivity
assigned on
SpecificationAssignment
DataValidityEffectivi
ty.startDefinition
DataValidityEffectivi endDate
ty.endDefinition
objectId.LocalId
=com.ptc.windchill.option.model.Op
tionSetMemberLink: +random number
Registered Option
Part 21 Representation
#1218= ANDCONDITION($,$,$,*,(#1178,#736),$);
#1224= NOTCONDITION($,$,$,*,(#1180),$);
#1225= ORCONDITION(#1229,CHARACTERSTRING('1621847369'),$,*,(#1224,
#600),$);
#1253= CONDITIONALCONFIGURATION($,$,$,$,$,$,$,$,$,#1225,
CLASSSTRING('usage'),CLASSSTRING('local'));
#1254= EFFECTIVITYASSIGNMENT($,$,$,CLASSSTRING('required'),#1253,
#43,.T.);
PART 21 Representation
#978= SPECIFICATIONCONDITIONASSIGNMENT(CHARACTERSTRING
('((null))'),$,CLASSSTRING('validity'),#979,#207);
#979= NOTEQUALSCONDITION($,$,$,*,(#464,#838),$);
#1016= SPECIFICATIONINCLUSION(#1018,CHARACTERSTRING
('((null))'),$,#770,#1090);
#1090= ANDCONDITION($,$,$,*,(#838,#736),$);
#1052= SPECIFICATIONINCLUSION(#1054,CHARACTERSTRING
('((null))'),$,#600,
#1092);
PART 21 Representation
#1096= SPECIFICATIONINCLUSION(#1098,CHARACTERSTRING('((null))'),$,
#1218,
#396);
#1097= SPECIFICATIONINCLUSIONASSIGNMENT($,$,#1096,#207);
#1218= ANDCONDITION($,$,$,*,(#1178,#736),$);
IndependentAssignedExpression
PART 21 Representation
#1218= ANDCONDITION($,$,$,*,(#1178,#736),$);
#1224= NOTCONDITION($,$,$,*,(#1180),$);
#1225= ORCONDITION(#1229,CHARACTERSTRING('1621847369'),$,*,(#1224,
#600),$);
#1253= CONDITIONALCONFIGURATION($,$,$,$,$,$,$,$,$,#1225,
CLASSSTRING('usage'),CLASSSTRING('local'));
#1254= EFFECTIVITYASSIGNMENT($,$,$,CLASSSTRING('required'),#1253,
#43,.T.);
OptionSetChoiceRuleLink
PART 21 Representation
#978= SPECIFICATIONCONDITIONASSIGNMENT(CHARACTERSTRING
('((null))'),$,CLASSSTRING('validity'),#979,#207);
#207= PRODUCTCLASS(#208,$,CHARACTERSTRING(' ((null))'),$,$,$,
IDENTIFIERSTRING('A.7'),$);
#1097= SPECIFICATIONINCLUSIONASSIGNMENT($,$,#1096,#207);
#207= PRODUCTCLASS(#208,$,CHARACTERSTRING(' ((null))'),$,$,$,
IDENTIFIERSTRING('A.7'),$);
RuleMemberActionLink
PART 21 Representation
#1096= SPECIFICATIONINCLUSION(#1098,CHARACTERSTRING('((null))'),$,
#1218,
#396);
#396= SPECIFICATION(#397,CHARACTERSTRING('choice 4.2'),
CHARACTERSTRING(
' ((null))'),IDENTIFIERSTRING('A.1'),$,#252,.F.);
If EffectivityAssignment.assignedTo is of
type PartVersion then Get relevant WTPart from
PartVersion WTPart.expressionData=
expressionJsonString else if
EffectivityAssignment.assignedTo is of
type NextAssemblyViewUsage then Get relevant
WTPartUsageLink from
NextAssemblyViewUsage
WTPartUsageLink.expressionData=
expressionJsonString
Part 21 Representation
#1218= ANDCONDITION($,$,$,*,(#1178,#736),$);
#1224= NOTCONDITION($,$,$,*,(#1180),$);
#1225= ORCONDITION(#1229,CHARACTERSTRING('1621847369'),$,*,(#1224,
#600),$);
#1253= CONDITIONALCONFIGURATION($,$,$,$,$,$,$,$,$,#1225,
CLASSSTRING('usage'),
ExpressionMemberLink
Part 21 Representation
#1052= SPECIFICATIONINCLUSION(#1054,CHARACTERSTRING(' ((null))'),
$,#600,
#1092);
#1092= ANDCONDITION($,$,$,*,(#943,#908,#1094),$);
#1094= NOTEQUALSCONDITION($,$,$,*,(#929,#887,#936),$);
#1218= ANDCONDITION($,$,$,*,(#1178,#736),$);
#1224= NOTCONDITION($,$,$,*,(#1180),$);
Part 21 Representation
#1133= ORCONDITION($,$,$,*,(#1132,#600),$);
#1134= ANDCONDITION(#1143,CHARACTERSTRING(' ((null))'),(#1141),*,
(#1133,#702),$);
#1218= ANDCONDITION($,$,$,*,(#1178,#736),$);
WTDatedEffectivity
Part 21 Representation
#1320= DATAVALIDITYEFFECTIVITY($,$,$,$,$,#1323,$,$,DATETIMESTRING
('2018-03-30T00:00:00'));
#1324= EFFECTIVITYASSIGNMENT($,$,$,CLASSSTRING('required'),#1320,
#1287,.T.);
ProductSerialNumberEffectivity
Part 21 Representation
#1406= SERIALEFFECTIVITY($,$,$,$,$,#1323,$,$,$,IDENTIFIERSTRING
('123456'),
IDENTIFIERSTRING('123456'));
#1407= EFFECTIVITYASSIGNMENT($,$,$,CLASSSTRING('configured'),
#1406,#77,.T.);
Implementation Examples
Implementation of the representing_part template is used as an example.
The intention is that you can develop or understand the template functions, if you
follow this example as a guideline.
Template Layers
Templates are layered on top of each other with the pure PLCS entities at the
bottom. The template functions are layered in exactly the same way. The sketch
underneath depicts the layers of the representing_part template definition.
Function Categories
For each template there are two mandatory functions, a Get get_
representing_part) function and a Create function (create_
representing_part). The Copy and Delete functions are implemented on
demand if needed.
Target Models
For target data models, which are implicitly opened for write, a simple call to
initTemplateAPI is used for initialization. If the ‘with_rdl’ parameter is
set to ‘FALSE’ no RDL is needed. This means that the converter is on its own
with respect to correctness of the classifications it uses. If the ‘with_rdl’
parameter is set to ‘TRUE’, the templateAPI looks for an RDL with the name
<target_model_name>_RDL or an RDL named plcsrdl as the default.
Source Models
Source models are implicitly opened for read. The initTemplateAPI function
will generate template extension instances if that has been done already.
Therefore, when the source model is a PLCS population, it must temporarily be
opened for write during the initialization stage. Afterwards the model should be
reopened for read only again, in order to prevent accidental (faulty) updates of the
source model.
xpxChangeOpenMode(XPXSOURCEMODELID,xpxRW);
PLCSMODELID := XPXSOURCEMODELID;
initTemplateAPI(TRUE);
xpxChangeOpenMode(XPXSOURCEMODELID,xpxRO);
PLCSMODELID is the identifier of the model addressed by the templateAPI.
By default PLCSMODELID is set to XPXTARGETMODELID. In case the source
model is a PLCS population, the PLCSMODELID must be switched to
XPXSOURCEMODELID during initialization. XPXSOURCEMODELID and
XPXTARGETMODELID are EDMxpx built in variables.
Init Function
The init function does not only initialize the templateAPI itself, but also the
model (PLCS population) on which the API operates. The representing_
part instances are initialized with the following call:
somestuff := get_representing_part(?,?,?,?,?,?,?,?,?);
init_rep_part := TRUE;
This call will return an aggregate of all representing_part instances. The
representing_part instances will be generated, if that has not been done
before. Instances of other template extension entity types are initialized in a
similar way. Since many templates are layered on top of other ones, some get_
xxxxx functions may call other ‘get functions’. Due to these dependencies the
order of the initialization calls is significant. For the same reason some of the
templates have their own private initialization flag in addition to the global one
(initialized).
Section 1
If template extension instances have been initialized before (private or global flag
is checked), the search section is entered. There is not any one recommended
method/way to implement the search. The implementation all depends on the
structure of the template.
Section 2
Section 2 is entered if template extension instances have not been initialized so
far. If you look at get_representing_part, Section 2 starts with:
xpxGetEntityExtentBN (PLCSMODELID,'Part_view_definition',prod_def_
bag);
REPEAT i := 1 TO SIZEOF(prod_def_bag);
.......
Create Functions
The main behavior of Create functions is simple in the sense that the client
application (converter) always calls the Create function without the need to check
beforehand whether an instance matching the input parameter already exists or
not. The Create function does that for you by calling the corresponding Get
function. So the Create function either creates and returns a new instance or
returns the instance identifier of an already existing one.
A create function has two main sections.
Section 2
In section two the main template instance (REPRESENTING_PART) is created.
Actually that is what takes place at the end of the function. As depicted in the
template layers diagram, template entities are layered on top of pure PLCS entities
and normally on top of other template entities as well. Not all instances belonging
to a template instance structure are created. To reduce the volume/size of the
population as much as possible, redundancy is avoided by reusing already existing
instances whenever possible. Using the create_representing_part as example the
steps in section-2 are described.
• Product_category / Product_category_assignment
There should be only one single Product_category (name = part) in a
population. It is reused and linked to all Parts through the Product_category_
assignment.products aggregate. The xpxGetEntityExtentBN returns all
instances of a given type. Normally there is a performance penalty when
iterating through the aggregate of instances returned. In this case, however,
this function can safely be used, since there is maximum one single instance of
Product_category_assignment in the whole population.
• Part
The get_assigning_identification function is used to find out if a Part with the
given identification already exists. If that is the case, that Part is reused.
Otherwise a new Part is created, and its identification is attached using the
create_assigning_identification function.
• Part_version
A list of all Part_versions for the Part is obtained. (this list is of course empty
if the Part was newly created) . For each Part_version in the list the get_
assigning_identification function is used to find out whether one of them has
an identification that matches the given input. If that is the case that Part_
version is reused. Otherwise a new Part_version is created and connected to
the Part. Its identification is attached, as well, using the create_assigning_
identification function.
• View_definiton_context
There are a very limited number if View_definiton_context instances in the
population. Therefore the aggregate returned by xpxGetEntityExtentBN can
safely be iterated over without any performance penalty. A View_definiton_
Copy Functions
Copy functions are not relevant when converting back and forth between legacy
data or proprietary format such as the Windchill Express schema. The Copy
functions are applicable when a DEX source population is merged into a target
DEX population. A prerequisite is that the source and target schema are the very
same one.
Copy functions consist of two rather simple steps. Copy functions take a source
(representing_part) instance as input. The input parameters required for
the create (create_representing_part) function are extracted from the
source instance. Then the create (create_representing_part) function is
invoked. The create function will either return an already existing instance or
create a new one. So applying the copy functions to all instances in a source
population, the resulting target population will become a union (or merge) of the
source population and the original target population.
Delete Functions
Delete functions are normally not relevant when converting back and forth
between legacy data or proprietary format such as the Windchill Express schema.
Such functions are applicable when a DEX database is maintained over time. For
instance in connections with applications like TruePLM.
Reference Data
Reference Data is data that represents information about classes or individuals
which are common to many users. Reference Data provides a tailorable structured
vocabulary that extends the PLCS information model with business-specific
semantics.
Capability
A Capability is a description of how EXPRESS entities are used to represent a
given concept (a specific "functionality" or "capability"). It provides guidance and
rules on what Entities are used to represent a given concept, how the entities are
related, and what Reference Data are used, as well as general guidance. A set of
Templates are documented within a Capability to provide precise specifications of
which Entities are instantiated to represent identified concepts.
Template
A Template is a precise specification of which entities and attributes in the ISO
10303-239 PLCS are instantiated. It also specifies which Reference Data should
be used to represent a concept providing documented functionality in a Capability.
A Template defined and managed by the OASIS PLCS TC is referred to as a
"PLCS Template", as opposed to a "Business Template."
Templates describe and specify how common business concepts are represented
using the PLCS information model. Templates have been defined at a fine grained
level to encourage maximum reuse across different DEXs, hence ensuring
consistent usage of the PLCS information model. For example, the Template
representing_organization is used to represent an organization, and can
be reused whenever this is required.
Reference Data
Reference data must be defined for every property associated with a Windchill
object.
There are some standard annotation-based properties which must be added to
newly added reference data and libraries. For details on the various annotation
properties, please refer “Guidance for PLCS RDL Developers” section in the
PLCS Guide for Reference Data Developer guide.
Reference data us managed in Windchill solution using the ISO_12006_
3VERSION_14 schema.
Note
The PLCS Guide for Reference Date Developer guide can be downloaded
from the OASIS Product Life Cycle Support (PLCS) Technical Committee
website from this external link: PLCS Guide for Reference Date Developer
Note
These manual steps have been incorporated into ant scripts. They can found at:
• <WT_HOME>\bin\configureAP239.xml
• <WT_HOME>\bin\configureSTEP.xml
Note
Model can be loaded using OWLs as well.
Note
Base units are simple units without having any multiplication, exponent or
division symbols whereas derived units are units which are generated from
base units. Business field names are configured against Assigned_property
parent class. Only for time based business field parent should be Date or Date_
and_time_assignment class.
WTPart Mapping
The following table depicts the common template mapping for WTPart and its
associated attributes.
Attribute Mapped Template
e_WTPart REPRESENTING_PART
Name assigning_identification
Number + (versionId + Iternation Id) + representing_part
Org Name
Ufid assigning_identification_with_no_
organization (associated to PART
VIEW DEFINITION)
masterufid assigning_identification_with_no_
organization (associated to PART)
view assigning_identification
lifeCycleState, assigning_product_property
lifeCycleTemplateName, domainName, product_property_text
externalTypeId, folderPath, defaultUnit,
partSource, partType, versionLevel,
defaultTraceCode, defaultUnit,
endItem, genericType
WTDocument Mapping
The following table depicts the common template mapping for WTDocument and
its associated attributes.
Attribute Mapped Template
e_WTDocument REPRESENTING_DOCUMENT
Name assigning_identification
Number + (versionId + Iternation Id) + representing_document
Org Name
Ufid assigning_identification_with_no_
organization (associated to document
version)
masterufid assigning_identification_with_no_
organization (associated to doc master)
BusinessField Mapping
BusinessFields (aka IBAs) are treated as simple properties associated to various
Windchill business objects. Based on the type of property, different templates
have been adopted for mapping purposes.
The following table depicts the common template mapping for BusinessField
and its related attributes based on the data type of property
Attribute Datatype Mapped Template
String, Boolean, HyperLink, Long, assigning_product_property
FloatingPoint product_property_text
FloatingPointWithUnits assigning_product_property
process_property_numeric
Timestamp assigning_time
WTPartDescribeLink Mapping
Express G Representation of WTPartDescribeLink and
WTPartReferenceLink.
The following figure shows the WTPart – WTDocument link.
WTPartReferenceLink Mapping
For Express G Representation of WTPartReferenceLink, see the WTPart –
WTDocument link diagram.
The following table describes the detailed template mapping for
WTPartReferenceLink and its associated attributes.
The following table describes the detailed template mapping for Representation
and its associated attributes.
Where,
• parameters refers to ObjectExportParameters.
• Boolean flag indicates that the execution happens inside method server stub.
• IXBExpImpStatus object carries the result of the export operation.
Following are the key export parameters and APIs which are required to perform
the export.
Parameter Description
setClientFileName The absolute file path where output jar
is created. Client filename must not
exist. It is a place holder where client is
expecting the output jars to be stored. If
the file path is not provided, then the
information is exported to a random
temporary location. PTC recommends
that you set this parameter for export.
setCollection wtCollection containing
persistable objects to export. Persistable
objects for which Import/Export
handler exists and is supported for
export. List of objects that are
supported OOTB can vary based on the
format type used. Refer to the related
standards documentation for details.
Import
Importing a jar to a given container is achieved through the following server-side
API:
IXBExpImpStatus expImpStatus
= IXBSvrHelper.service.doImport(objectimportparameters,true);
Note
Consider the file through streamer object instead of repository.
/**
* Get value of attribute ServiceDescriptor
*/
public String getServiceDescriptor ();
/**
* Assign value to attribute ServiceDescriptor
*/
public void setServiceDescriptor (String value);
/**
* Get value of attribute IterationC11nInstruction
*/
public IterationC11nInstruction.Iterator
getIterationC11nInstruction ();
/**
* Size of collection IterationC11nInstruction
*/
public int sizeOfIterationC11nInstruction ();
/**
* Get content of collection IterationC11nInstruction as array
*/
public IterationC11nInstruction<]
getIterationC11nInstructionArray ();
//
// $$NONE
//
package com.ptc.windchill.uwgm.soap.uwgmsvc;
import com.ptc.windchill.uwgm.soap.bins11n.*;
import com.ptc.cipjava.*;
import com.ptc.windchill.uwgm.soap.uwgm.*;
import com.ptc.windchill.uwgm.soap.bins11n.*;
/**
*
*/
@UwgmBinRegisterable
public interface WorkspaceC11nRequest
extends UwgmRequest, C11nRequest, WithWorkspace
{
public final static UwgmRequestType type = new
UwgmRequestType("uwgmsvc::WorkspaceC11nRequest");
/**
* Assign value to attribute ResponseData
*/
public void setResponseData (stringdict value);
/**
* Size of collection IterationC11nResponse
*/
public int sizeOfIterationC11nResponse ();
/**
* Get content of collection IterationC11nResponse as array
*/
public IterationC11nResponse[] getIterationC11nResponseArray
();
//
// $$NONE
//
package com.ptc.windchill.uwgm.soap.uwgmsvc;
import com.ptc.windchill.uwgm.soap.bins11n.*;
import com.ptc.cipjava.*;
import com.ptc.windchill.uwgm.soap.uwgm.*;
import com.ptc.windchill.uwgm.soap.bins11n.*;
/**
*
*/
@UwgmBinRegisterable
public interface WorkspaceUpdateC11nMessage
extends UwgmMessage, C11nMessage, WorkspaceUpdateMessage
{
public final static UwgmMessageType type = new
UwgmMessageType("uwgmsvc::WorkspaceUpdateC11nMessage");
/**
* The Cutsom service delegate is expected to implement execute
* @param c11nCtx
: com.ptc.windchill.uwgm.proesrv.c11n.C11nRequestContext
* @param c11nInstructions
: Map<String, String>
* @param c11nIterationInstructions
: Map<Persistable, Map <String, String>>
* @param ws
: EPMWorksapce
* @return UwgmC11nResponse
: com.ptc.windchill.uwgm.proesrv.c11n.UwgmC11nResponse
* @throws WTException
: Exception
* @throws ConflictException
: Conflict
*/
public UwgmC11nResponse executeInWS(C11nRequestContext
c11nCtx,
EPMWorkspace ws,
Map<String, String> c11nInstructions,
Map<Persistable, Map<String, String>>
c11nIterationInstructions) throws WTException,
ConflictException;
}
/**
* returns current client's locale
* @return Locale
*/
public Locale getLocale();
/**
* returns client canonic name
* @return String
*/
public String getClientName();
/**
* returns client canonic version
* @return int
*/
public String getClientVersion();
/**
* returns the session information of the Client
* @return String
*/
public String getClientSessionID();
/**
* retruns the name of the PDM request
* @return String
*/
public String getRequestName ();
}
/**
* It is expected that the client recieving the response
* understands the semantics
* of the keys; and accordingly interprets the
* value of the response.
* @return Map <String, String>
*/
public Map<String, String> getResponseData()
{
return responseData;
}
/**
* Response elements associated to the Persistable.
* It is expected that the client recieving the response s
* understand the semantics of the key; and accordingly
* interprets the value of the entries in the String Map
* associated with each Persistable in the Map.
*
* @return Map<Persistable, Map<String, String>>
*/
public Map<Persistable, Map<String, String>>
getIterationResponseData()
{
return iterationResponseData;
}
/**
* logging
*/
private static Log log = LogFactory.getLog(UwgmC11nResponse.
class);
}
An example implementation of UwgmC11nService is provided in your
Windchill installation at <Windchill>/codebase/com/ptc/
windchill/uwgm/proesrv/c11n/UwgmC11nServiceTest.java for
reference only. You are not expected to reuse this class. You need to implement
your own server-side customization as per your needs.
<Configuration targetFile="codebase/service.properties">
<Service context="default"
name="com.ptc.windchill.uwgm.proesrv.c11n.UwgmC11nService">
<Option cardinality="duplicate" requestor="java.lang.
Object"
selector="UWGMC11N_UNIT_TEST"
serviceClass="com.ptc.windchill.uwgm.proesrv.c11n.
UwgmC11nServiceTest"/>
<Option cardinality="duplicate"
requestor="java.lang.Object"
selector="UWGMWSC11N_UNIT_TEST"
serviceClass="com.ptc.windchill.uwgm.proesrv.c11n.
UwgmC11nServiceTest"/>
</Service>
</Configuration>
The selector provides the key to be able to locate a registered service. This key
forms the ServiceDescriptor attribute of the C11nRequest; and helps the
application services infrastructure to invoke appropriate services.
It is important that your custom code needs to pass this key properly in the Uwgm
Request to execute a custom code on the server.
You must use the xconfmanager utility to propagate changes in
application.service.xconf file to the service.properties file.
UWGMEventListener
Below is the description of the UWGMEventListener API that a custom
EventHandler code needs to implement.
public interface UwgmEventListener
{
/**
* API to process UwgmEvent
* Custom UwgmEventService delegate should implement this API.
*
* @param iteration : Collection of request Iterations
* @param workspace : EPMWorkspace
* @return WTCollection : Response
* @throws WTException
*/
}
Am example implementation of UWGMEventListener is provided in your
Windchill installation at <Windchill>codebase/com/ptc/windchill/
uwgm/proesrv/c11n/UwgmC11nEventListenerTest.java for
reference purposes only. You are not expected to reuse this class. You need to
implement your own server-side customization as per your own needs.
<Service context="default"
name="com.ptc.windchill.uwgm.proesrv.c11n.UwgmEventListener">
<Option cardinality="duplicate"
Reviewing Transaction
An ESI transaction can be accessed from the ESI Transaction Log page (available
from Site ▶ Utilities) page for an Organization Administrator. Each transaction will
be associated to a job. User can navigate to corresponding job details page using a
context (RMB) menu action on a specific transaction.
2003
Adding a ThingWorx Mashup to Windchill
How to add a ThingWorx mashup to Windchill.
The site administrator is able to add ThingWorx actions into the Windchill UI to
embed ThingWorx mashups within the Windchill page or launch ThingWorx
mashups ‘standalone’ in separate window or browser tab.
Prerequisites
• Windchill 11.0+ server
• ThingWorx server (and a ThingWorx mashup to be added to Windchill UI)
Note
This property could contain URL parameters if desired.
Note
The direct URL to the menu is: <server>/<webapp>/app/#ptc1/
carambola/tools/list?tab=customization
2. Search for the action model of interest to find its corresponding info page.
ThingWorx 2005
3. From the action model, info page actions can be added into the model, See
Create new ThingWorx Action in the Model on page 2008 for instructions.
ThingWorx 2007
Creating a new ThingWorx Action in the Model
The site administrator has actions available in the toolbar to create/remove/paste
actions into the model. Those actions update the <wt home>/codebase/
custom-actions.xml and <wt home>/codebase/custom-
actionmodels.xml files as necessary and then all the action definitions are
reloaded.
1. Create an Action.
2. On step 1 of the wizard provide the Label, Name, and Object Type. These can
be any values.
3. On step 2 of the wizard provide the URL. The URL must be: ptc1/
twx?mashup=<name of mashup>
Note
Currently it is not supported to pass additional parameters to the mashup via
the action URL.
ThingWorx 2009
For popups, the ThingWorx content would not be in any iframe. The default size
of the popup window may not match the content, but the user would be able to
resize the window. The window size is not sticky. It is possible in the XML action
definition to control the size of the popup with <moreurlinfo>height=
1000,width=1200</moreurlinfo>. This change must be made by editing
the action xml files directly, because the the moreurlinfo param is not currently set
via the action model report UI.
ThingWorx 2011
•
X-Frame-Options
• DENY - The page cannot be displayed in a frame, regardless of the site
attempting to do so.
• SAMEORIGIN - The page can only be displayed in a frame on the same origin
as the page itself.
• ALLOW-FROM http://example.com - The page can only be displayed in
a frame on the specified origin.
Content-security-policy
• frame-ancestors ‘none’ - Prevents loading resources in a frame from
any origin.
• frame-ancestors ‘self’ - Allows loading resources in a frame but only
from the same origin.
• frame-ancestors domain1.com domain2.com - Allows loading
resources in a frame but only from domains in the given list.
ThingWorx Support
Configuration
ThingWorx will support both headers through the use of a Http request filter. The
administrator will be able to enable or disable one of three filters:
ClickjackFilterDeny, ClickjackFilterSameOrigin, and
ClickjackFilterWhiteList by uncommenting one of the three filter
mappings in the web.xml file of the ThingWorx application.
For example:
<!-- use the Deny version to exclude all framing -->
<!--
<filter-mapping>
<filter-name>ClickjackFilterDeny</filter-name>
ThingWorx 2013
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<!-- use the SameOrigin version to allow your application to frame, but
nobody else -->
<!--
<filter-mapping>
<filter-name>ClickjackFilterSameOrigin</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<!-- use the WhiteList version to allow framing from specified domains
-->
<filter-mapping>
<filter-name>ClickjackFilterWhiteList</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Note
There is a restriction to the Allow-From header. It will only allow a single
domain.
Arbortext Editor (version 5.4 F000 and later) is capable of downloading a zipped
custom directory structure using HTTP, extracting its contents to a temporary
file system location, and using that as a custom directory. This allows
administrators to store Arbortext doctypes and other customizations in Windchill.
Windchill makes the zipped custom directories available by designating a
special anonymous access folder whose contents will be made available over
anonymous HTTP. The HTTP access is anonymous so the user is not presented
with an unexpected credentials prompt during Arbortext Editor startup.
2015
Anonymous Arbortext Access
Process Overview
To host an XML Application in Windchill and use it from Arbortext Editor:
1. Create a zip archive of the custom directory structure.
2. Log in to Windchill, locate a Product or Library (or create one if needed), and
then select the Folders second-level navigation for the container.
Note
Only Products and Libraries are supported. Other containers (Site, Org,
Program, Project) are not supported by this feature.
3. Create a folder (if needed) to hold the Arbortext customizations. This folder
can be at the top-level or it can be nested inside some other folder (at any
depth).
4. Inside that same Product or Library, bring up the Preference Management
utility, expand the Arbortext preference group, and locate the Customizations
Folder preference.
5. Edit that preference and enter the name and path of the desired folder. Some
example values are:
Value Description
Arbortext Customizations Top level folder with a space in the
folder name.
Arbortext/Applications Top level folder called “Arbortext”
with a child folder called
“Applications”.
Having set this preference, any WTDocument objects in the specified folder
will now be available via anonymous HTTP. (specific details on constructing
the URL will come later in this document).
6. Upload the zip file into the desired folder. When creating the document in
Windchill, the “Type” and “CAGE Code” values do not matter.
7. Put the anonymous access URL for your archive into the browser and verify
that you can successfully download the zipped archive. See the section
“Anonymous Access URL Format” for information on the anonymous access
URL.
8. Set the APTCUSTOM environment variable to the anonymous access URL for
your zip archive and launch Arbortext Editor to use the customizations.
Note
The folder name itself is not contained in the URL. The folder name is defined
in the Customizations Folder preference. See “Configuring the Folder Path for
Anonymous Access” section for information on setting this preference.
Note
As is normal for HTTP URLs, some characters, like spaces, colons, and non-
Latin characters will need to be escaped in the URL; for example, space
characters will need to be replaced with %20.
If you specify the name of an object which does not exist in the folder, or no
iteration of the object matches the given request parameters, the anonymous
access URL will return a 404 response to the caller. This is normal HTTP
behavior when the requested object is not found.
Note
Selecting the “Latest” Version
When dealing with versioned Windchill objects, the convention is that the
“latest” object is selected by version and then by iteration. The latest iteration
in version D will always be considered “newer” than the latest iteration in
version C, even if that iteration was created more recently. For example, when
browsing folder contents using the web UI, you’ll always see the latest
iteration from the latest version, even if there are newer iterations in other
versions.
The version selection for anonymous access URLs works in this way. For
example, if the state parameter is specified without a version, and A.4 and B.2
both have the requested state, B.2 will always be returned regardless of when
A.4 was created.
Note
For more information on zipped Arbortext customizations, see the
"Deploying zipped customizations" section of the Arbortext Help Center
(Programming > Arbortext Customizer's Guide > Custom applications >
Deploying zipped customizations).
------------------------------------------------------------------
-------------
!+! ENTERING Anonymous Access
------------------------------------------------------------------
-------------
listAvailableResources:
[echo]
------------------------------------------------------------------
[echo] The following is a list of documents in Windchill that
are exposed
[echo] to anonymous http access. Each entry lists the
Organization,
[echo] Product or Library, and Name of the document as well
as the Url
[echo] used to access it.
[echo]
------------------------------------------------------------------
[java]
[java] Organization: Demo Organization
[java] Library: New Library
BUILD SUCCESSFUL
Total time: 9 seconds
Note that the example URLs do not contain actual hostname and web-app
values because these values are unavailable through the command line interface.
The URLs displayed are quite long and break across lines in the command
prompt. Viewing the log file referred to at the beginning of the listing is an easier
way of viewing the output.
This list includes all document objects being shared throughout your Windchill
installation, including all products and libraries in all organizations.
*****************************************************************-
*************
!+! STARTED @ Fri Oct 14 14:19:59 CDT 2011
*****************************************************************-
*************
Created log dir <Windchill>\Windchill\buildlogs'
------------------------------------------------------------------
-------------
!+! ENTERING Anonymous Access[<Windchill>\Windchill\bin
\anonymousAccess.xml]
------------------------------------------------------------------
-------------
listAvailableResources:
[echo]
------------------------------------------------------------------
[echo] The following is a list of documents in Windchill that
are exposed
[echo] to anonymous http access. Each entry lists the
Organization,
BUILD SUCCESSFUL
Total time: 24 seconds
Defining Attributes
To define global and standard attributes for the custom configuration specification,
perform these steps:
1. Search for a type managed by the custom configuration in the Type Manager.
2. Create the required global or local attributes. Custom configuration
specification type has also two MBA attributes, View and Effectivity Context,
that you can use in your customization.
3. Add the attributes that you require for the customization in the Edit Filter
layout.
4. Set the CUSTOM_CONFIG_SPEC_ENABLED property in the
wt.properties file to True.
5. Save and restart Windchill to make your custom configuration specification
visible in the Edit Filter widget.
6. (Optional) Change the display name of the custom configuration specification.
Note
You can use multivalued attributes while customizing configuration
specifications. For more information, see Using MultiValued Attributes in
Customizing Configuration Specifications on page 2062.
Implementing Logic
To implement the logic, perform these steps:
1. Create a new class that implements
wt.vc.config.custom.CustomConfigSpecDelegate.
2. Override the appendSearchCriteria method to provide the custom
logic responsible for creating query that is used to resolve the structure to the
version.
3. Override the process method to provide the custom logic responsible for
processing the QueryResult of iterations, returning only those that match
with the algorithm.
4. Override the setAttributesMap and getAttributesMap methods
that are used to provide attributes values passed from the Edit Filter widget.
Note
If you want to use different global attributes in your customization, ensure
that you make appropriate changes in example customization in the
following steps.
Effectivity Type:
Effectivity Unit:
import java.util.Map;
import wt.fc.ObjectReference;
@Override
public QuerySpec appendSearchCriteria(QuerySpec querySpec) throws
WTException, QueryException {
QuerySpec clone = (QuerySpec) querySpec.clone();
View view = (View) ((ObjectReference)getAttributesMap().get(VIEW_
REF).getValue()).getObject();
ObjectReference context = (ObjectReference) getAttributesMap().get(EFF_
CONTEXT).getValue();
String effType = (String) getAttributesMap().get(EFF_TYPE).getValue();
String effUnit = (String) getAttributesMap().get(EFF_UNIT).getValue();
WTPartEffectivityConfigSpec effConfigSpec =
WTPartEffectivityConfigSpec.newWTPartEffectivityConfigSpec();
try {
effConfigSpec.setView(view);
effConfigSpec.setEffectiveContextRef(context);
effConfigSpec.setEffType(effType);
effConfigSpec.setEffectiveUnit(effUnit);
} catch (WTPropertyVetoException e) {
e.printStackTrace();
}
@Override
public QueryResult process(QueryResult results) throws WTException {
return results;
}
@Override
public void setAttributesMap(Map<String, CustomConfigSpecAttribute>
attributesMap) {
this.attributesMap = attributesMap;
}
@Override
public Map<String, CustomConfigSpecAttribute> getAttributesMap() {
return attributesMap;
}
}
Now plug in the logic by performing the steps in the Plugging in the Logic section
above.
Result
The custom configuration statement is visible in the Edit Filter layout and can
resolve the structure using the custom logic that you have specified:
Note
If you want to use different global attributes in your customization, ensure
that you make appropriate changes in example customization in the
following steps.
import java.lang.reflect.Constructor;
import java.sql.Timestamp;
import java.util.Map;
import wt.eff.Eff;
import wt.eff.EffContext;
import wt.eff.EffManagedVersion;
import wt.eff.EffRange;
import wt.eff.LeftFilledStringEffRange;
import wt.eff.QueryHelper;
import wt.effectivity.WTDatedEffectivity;
import wt.fc.ObjectIdentifier;
import wt.fc.ObjectNoLongerExistsException;
/**
@SuppressWarnings("deprecation")
@Override
public QuerySpec appendSearchCriteria(QuerySpec querySpec) throws
WTException, QueryException {
clone = appendLatestIteration(clone);
clone.appendAnd();
clone.appendOpenParen();
clone = appendSerialEffSubSelect(clone, branchId);
clone.appendOr();
clone = appendDateEffSubSelect(clone, branchId);
clone.appendCloseParen();
return clone;
}
@SuppressWarnings("deprecation")
private QuerySpec appendDateEffSubSelect(QuerySpec clone,
ClassAttribute branchId) throws QueryException, WTException {
clone.appendOpenParen();
QuerySpec dateSelect = new QuerySpec();
try {
dateSelect.getFromClause().setAliasPrefix("E2");
} catch (WTPropertyVetoException wtpve) {
// Do nothing...
}
// SELECT branchIdA3targetReference
// FROM wt.effectivity.WTDatedEffectivity E20
dateSelect.addClassList(WTDatedEffectivity.class, false);
ClassAttribute productDateTargetRef = new
ClassAttribute(WTDatedEffectivity.class, TARGET_REF);
dateSelect.appendSelect(productDateTargetRef, 0, false);
clone.appendWhere(new ExistsExpression(dateSelect));
clone.appendCloseParen();
return clone;
}
@SuppressWarnings("deprecation")
private QuerySpec appendLatestIteration(QuerySpec clone) throws
QueryException, VersionControlException {
clone.appendAnd();
clone.setAdvancedQueryEnabled(true);
Class latestClass = clone.getClassAt(0);
clone.appendWhere(VersionControlHelper.getSearchCondition(latestClass,
true));
return clone;
}
@SuppressWarnings("deprecation")
private QuerySpec appendSerialEffSubSelect(QuerySpec clone,
ClassAttribute branchId)
throws QueryException, WTException,
ObjectNoLongerExistsException {
clone.appendOpenParen();
QuerySpec serialEffSelect = new QuerySpec();
try {
serialEffSelect.getFromClause().setAliasPrefix("E1");
} catch (WTPropertyVetoException wtpve) {
// Do nothing...
}
// SELECT E10.branchIdA3targetReference
// FROM wt.part.ProductSerialNumberEffectivity E10
// AND ((E10.branchIdA3targetReference =
A0.branchIditerationInfo)
serialEffSelect.appendAnd();
appendBranchId(clone, branchId, serialEffSelect, dTargetRef);
clone.appendWhere(new ExistsExpression(serialEffSelect));
clone.appendCloseParen();
return clone;
}
@SuppressWarnings("deprecation")
private void appendSerialEffRange(QuerySpec subSelect) throws
QueryException {
subSelect.appendOpenParen();
subSelect.appendWhere(getEffSearchCondition(START,
SearchCondition.GREATER_THAN_OR_EQUAL,
ProductSerialNumberEffectivity.class));
subSelect.appendAnd();
subSelect.appendWhere(getEffSearchCondition(END,
SearchCondition.LESS_THAN_OR_EQUAL,
ProductSerialNumberEffectivity.class));
subSelect.appendCloseParen();
}
}
return null;
}
@Override
public QueryResult process(QueryResult results) throws WTException {
return results;
}
@Override
public void setAttributesMap(Map<String, CustomConfigSpecAttribute>
attributesMap) {
effContextRef = (ObjectReference) attributesMap.get(EFF_
CONTEXT).getValue();
inputTimestamp = (Timestamp) attributesMap.get(EFF_DATE).getValue();
Result
The Custom Configuration Statement is visible in the Edit Filter layout, and can
resolve the structure according to the custom logic:
1. Search for the Custom Configuration Statement managed type in the Type
Manager.
Note
If you use different internal names for the attributes in your customization,
ensure that you make appropriate changes in the example customization in
the following steps.
Effectivity Range
import java.lang.reflect.Constructor;
import java.sql.Timestamp;
import java.util.Map;
import wt.eff.Eff;
import wt.eff.EffContext;
import wt.eff.EffManagedVersion;
/**
* This example will search for the revision which has serial effectivity
in range given as an input.
* If no revision is found it will look for revision which has date
effectivity which starts range is eariler
* than the one given in the input.
*
* We want to end up with this kind of query in querySpec:
*
* SELECT classnameA2A2,
* idA2A2
* FROM wt.part.WTPart A0
* WHERE (A0.idA3masterReference IN (109490,
* 109189,
* 110167,
* 109654,
* 110136,
* 108859,
* 109886))
* AND (A0.classnamekeycontainerReferen <>
'wt.projmgmt.admin.Project2')
* AND (A0.latestiterationInfo = 1)
* AND ((EXISTS
* (SELECT E10.branchIdA3targetReference
* FROM ProductSNEffectivity E10
* WHERE (((E10.idA3deletionReference IS NULL)
* OR (E10.idA3deletionReference = 0))
* AND (E10.branchIdA3targetReference =
A0.branchIditerationInfo)
* AND (E10.idA3effContextReference = 108617)
* AND ((E10.startrange >= 100)
* AND (E10.endrange <= 800)))))
* OR (EXISTS
* (SELECT E20.branchIdA3targetReference
* FROM WTDatedEffectivity E20
* WHERE (((E20.idA3deletionReference IS NULL)
* OR (E20.idA3deletionReference = 0))
* AND (E20.branchIdA3targetReference =
A0.branchIditerationInfo)
* AND (E20.startrange <= TO_
DATE('2019:03:25:23:00:00', 'YYYY:MM:DD:HH24:MI:SS')))))) *
@SuppressWarnings("deprecation")
@Override
public QuerySpec appendSearchCriteria(QuerySpec querySpec) throws
WTException, QueryException {
clone = appendLatestIteration(clone);
clone.appendAnd();
clone.appendOpenParen();
clone = appendSerialEffSubSelect(clone, branchId);
clone.appendOr();
clone = appendDateEffSubSelect(clone, branchId);
clone.appendCloseParen();
return clone;
}
@SuppressWarnings("deprecation")
private QuerySpec appendDateEffSubSelect(QuerySpec clone,
ClassAttribute branchId) throws QueryException, WTException {
clone.appendOpenParen();
QuerySpec dateSelect = new QuerySpec();
try {
dateSelect.getFromClause().setAliasPrefix("E2");
} catch (WTPropertyVetoException wtpve) {
// Do nothing...
}
// SELECT branchIdA3targetReference
// FROM wt.effectivity.WTDatedEffectivity E20
dateSelect.addClassList(WTDatedEffectivity.class, false);
clone.appendWhere(new ExistsExpression(dateSelect));
clone.appendCloseParen();
return clone;
}
@SuppressWarnings("deprecation")
private QuerySpec appendLatestIteration(QuerySpec clone) throws
QueryException, VersionControlException {
clone.appendAnd();
clone.setAdvancedQueryEnabled(true);
Class latestClass = clone.getClassAt(0);
clone.appendWhere(VersionControlHelper.getSearchCondition(latestClass,
true));
return clone;
}
@SuppressWarnings("deprecation")
private QuerySpec appendSerialEffSubSelect(QuerySpec clone,
ClassAttribute branchId)
throws QueryException, WTException,
ObjectNoLongerExistsException {
clone.appendOpenParen();
QuerySpec serialEffSelect = new QuerySpec();
serialEffSelect.addClassList(ProductSerialNumberEffectivity.class,
false);
ClassAttribute dTargetRef = new
ClassAttribute(ProductSerialNumberEffectivity.class, TARGET_REF);
serialEffSelect.appendSelect(dTargetRef, 0, false);
// AND ((E10.branchIdA3targetReference =
A0.branchIditerationInfo)
serialEffSelect.appendAnd();
appendBranchId(clone, branchId, serialEffSelect, dTargetRef);
clone.appendWhere(new ExistsExpression(serialEffSelect));
clone.appendCloseParen();
return clone;
}
@SuppressWarnings("deprecation")
private void appendEffContext(QuerySpec subSelect) throws
ObjectNoLongerExistsException, QueryException {
if (getEffContext() != null) {
subSelect.appendWhere(new
SearchCondition(ProductSerialNumberEffectivity.class,
EFF_CONTEXT_REF, SearchCondition.EQUAL,
(ObjectIdentifier) effContextRef.getKey()));
}
}
@SuppressWarnings("deprecation")
private void appendSerialEffRange(QuerySpec subSelect) throws
QueryException {
subSelect.appendOpenParen();
subSelect.appendWhere(getEffSearchCondition(START,
SearchCondition.GREATER_THAN_OR_EQUAL,
ProductSerialNumberEffectivity.class));
subSelect.appendAnd();
subSelect.appendWhere(getEffSearchCondition(END,
SearchCondition.LESS_THAN_OR_EQUAL,
ProductSerialNumberEffectivity.class));
subSelect.appendCloseParen();
}
@Override
public QueryResult process(QueryResult results) throws WTException {
return results;
}
}
}
Example
@Override
public QueryResult process( QueryResult results )
throws WTException {
if (results == null || !results.hasMoreElements())
return results;
/**
* 1) Get Original to working copies map for all the checked
out objects in QueryResult
* 2) Inflate the Value - so that we have inflated working
copies
* 3) Iterate over keySet i.e. Original copies.
* 3.1) Check if the session user has checked out the object
* - if yes, then get its working copy from the map.
* - Remove the original copy from the query result.
* - Add the working copy to query result.
*
* @param results - containing working copies of checkout out
workables for which
* user has access.
* @return
* @throws WorkInProgressException
* @throws WTException
*/
private ObjectVectorIfc handleWorkingCopies(QueryResult
results) throws WorkInProgressException, WTException {
ObjectVectorIfc resultVector = results.getObjectVectorIfc
();
WTValuedMap orgToWrkMap = WorkInProgressHelper.service.
getCheckedOutToWorkingMap(new WTArrayList(results));
boolean isAccessEnforced = SessionServerHelper.manager.
setAccessEnforced(false);
try {
orgToWrkMap.wtValues().inflate();
} finally {
Example
@Override
public QuerySpec appendSearchCriteria( QuerySpec querySpec )
throws WTException, QueryException {
QuerySpec qs = (QuerySpec) querySpec.clone();
qs.appendAnd();
qs.appendWhere(new SearchCondition(Workable.class,
Workable.CHECKOUT_INFO+"."+CheckoutInfo.STATE,
SearchCondition.NOT_EQUAL, WorkInProgressState.WORKING), new
int[]{0});
return qs;
}
Alternatively, you can achieve the same in the process method using the
WorkInProgressHelper.isWorkingCopy API to determine whether
given iteration is a Working version. If it is not, you can exclude it from the result.
@Override
public QueryResult process(QueryResult results) throws
WTException {
Note
If you use different global attributes in the customization, ensure that you
make appropriate changes in the example customization in the next steps.
Result
The customization that you just created, resolves parts to the version based on the
serial effectivity. To test whether this works correctly, add Serial Effectivities for
some revisions of parts in the structure. Then use the CustomConfigSpec to
verify whether it resolves the structure to the correct versions based on the
effectivity context and range given as input.
1. Create Serial Effectivity for the part.
<script>
PTC.editfilter = {};
PTC.editfilter.customconfigspec = {};
PTC.editfilter.customconfigspec.setData = function(selectedDocuments)
{
var csObjectReferenceOverlay = {}
csObjectReferenceOverlay.displayValue =
selectedDocuments.pickedObject[0].name;
csObjectReferenceOverlay.objectId =
selectedDocuments.pickedObject[0].oid;
opener.PTC.cat.setObjectReference(csObjectReferenceOverlay);
}
window.onunload = function() {
opener.PTC.cat.unlockEditFilterUi();
}</script>
<wctags:itemPicker
id="changeNoticePicker"
componentId="deliverableActivitySubjectsPicker"
objectType="wt.change2.WTChangeOrder2"
showTypePicker="false"
inline="true"
pickerTitle="<%= request.getParameter(\"title\") %>"
showWorkingCopy="true"
pickerCallback="PTC.editfilter.customconfigspec.setData"/>
<objecttype name="standardChangeNotice2">
<action name="CustomConfigSpecObjReferenceSearchPicker">
<command url="netmarkets/jsp/ec/changeNoticePicker.jsp" />
<moreurlinfo>height=300,width=600</moreurlinfo>
<title>title2 </title>
</action>
</objecttype>
The <title> value and all the <moreurlinfo> values are passed to the JSP
as path parameters. For example, title=title1, height=300, width=500 will be
passed as path parameters for standardChangeNotice attribute.
Note
To apply this procedure, you must have an understanding of the basic web
development using JAVA.
Note
For more information on the xconfmanager, see Using the xconfmanager
Utility
Example
This example displays how to get the custom filter working.
<Configuration targetFile="codebase/service.properties"?
<Service context="default" name="wt.filter.NavigationFilterDelegate2">
<Option cardinality="singleton" requestor="null" serviceClass=
"wt.filter.custom.ExampleCustomFilterDelegate"
selector="WCTYPE|wt.filter.custom.CustomFilter|org.rnd.TestFilter"/>
</Service>
<Service context="default" name="NavigationCriteria.renderer">
<Option requestor="null" cardinality="singleton" selector=
"WCTYPE|wt.filter.custom.CustomFilter|org.rnd.TestFilter"
serviceClass=
"com.ptc.expansionui.client.ui.renderer.ExampleCustomFilterRenderer"
/>
</Service>
<Service context="default" name="NavigationCriteria.validator">
<Option requestor="null" cardinality="singleton" selector=
"WCTYPE|wt.filter.custom.CustomFilter|org.rnd.TestFilter"
serviceClass=
"com.ptc.expansionui.server.validator.ExampleCustomFilterTabValida
tor"/>
</Service
<Service context="default" name="NavigationCriteria.populator">
<Option requestor="null" cardinality="singleton" selector=
"WCTYPE|wt.filter.custom.CustomFilter|org.rnd.TestFilter"
serviceClass=
"com.ptc.expansionui.server.populator.ExampleCustomFilterPopulator" />
</Service>
</Configuration>
2. In the $WT_HOME/codebase/com/ptc/expansionui/
ExpansionCriteriaCore-wt.properties.xconf file, uncomment
the following line:
<Property name="NavigationCriteria.filters.order.xx" default=
"WCTYPE|wt.filter.custom.CustomFilter|org.rnd.TestFilter"/>
3. Propagate the xconf changes by running the following command from the
windchill shell:
xconfmanager -fp
Note
For more information on Java Annotations see Modeling Business Objects on
page 2171.
Note
See the Javadoc for
com.ptc.windchill.annotations.metadata.Changeable.
This section describes how to customize the Part Structure Browser (PSB).
Note
• Only GWT actions can be added to the Actions toolbar.
• Any customizations in the psb-actions.xml must be reviewed and
reapplied with each software update.
2. Add the display value for the action in the rbInfo file defined on the
resourceBundle parameter.
3. Add the model definition in the appropriate custom-actionmodels.xml
file. The RibbonInfo tag used in the actionmodel.xml file defines the
key characteristics about the action in the Actions toolbar. For more
information about the action definition RibbonInfo attributes, see the
“RibbonInfo Attributes” section below. The following is an example of adding
customActionGWT to the Part Structure Browser toolbar:
<model name="psbRelatedPartsTreeToolBar">
<!--Custom GWT Group-->
<action name="CustomActionGroupGWT" type="psb" >
<ribbonInfo columnCount="1" buttonType="group"/>
</action>
RibbonInfo Attributes
The following are the attributes of the RibbonInfo tag:
• buttonType: Button type can have different values such as button, menu,
text_menu, submenu, toggle, custommenu, split, check, subcheck, menuitem,
submenuitem, and group:
○ Button: Plain button that executes the action.
○ Menu: Button with a drop-down menu of actions. There is no action for
the button.
○ Split: Button that is both an action button and a menu button.
○ Toggle: Sticky button indicating an on or off state.
○ Text_Menu: Displays only text without any icon. It ignores the preference
that toggles the toolbar text. For example, used for an Action button.
○ Custom_Menu: Provides a way for menu plug-in that handles all the menu
items, actions, and events within.
○ Menu Items: The following are the allowed menu items:
◆ Menu_Item: An action on a menu. Action and label are required but
the icon is optional.
◆ Check: A menu item that indicates on or off state with a check mark
instead of an icon. For a group of actions, this turns into a radio button
and becomes exclusive with other check menu items with the same
group name.
◆ Sub-menu: A menu item that has a fly-out submenu. No action is
associated with it.
◆ Sub-menu Item: A menu item for a submenu.
Note
The CustomSearchAndLaunchURLAction is the default
implementation class. You can define your own class that implements the
SearchWidgetAction interface.
Note
It is not required to provide the value for buttonscale since it is
redundant, as the buttonscale value is always SMALL.
Example
xconfmanager -s "gwt.buttontype.searchwidget.ActionNames=customActionGWT"
-t codebase/wt.properties -p
xconfmanager -s
"gwt.buttontype.searchwidget.customActionGWT.SearchOnAttribute=name" -t
codebase/wt.properties -p
xconfmanager -s
"gwt.buttontype.searchwidget.customActionGWT.SearchAttributeOnType=
wt.epm.EPMDocument" -t codebase/wt.properties -p
xconfmanager -s
"gwt.buttontype.searchwidget.customActionGWT.SearchOnTypes=
wt.epm.EPMDocument,wt.doc.WTDocument" -t codebase/wt.properties -p
xconfmanager -s
"gwt.buttontype.searchwidget.customActionGWT.AttributesToLoad=state" -t
codebase/wt.properties -p
Example
customTable.jsp
<% request.setAttribute(NmAction.SHOW_CONTEXT_INFO, "false"); %>
<%@ page import="wt.part.WTPart,
com.ptc.windchill.enterprise.part.partResource"%>
<%@ include file="/netmarkets/jsp/util/begin.jspf"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/components" prefix=
"jca"%>
<%@ taglib uri="http://www.ptc.com/windchill/taglib/fmt" prefix="fmt"%>
serviceName=
"com.ptc.windchill.enterprise.part.commands.PartDocServiceCommand"
methodName="getAssociatedReferenceDocuments" >
<jca:addServiceArgument type="wt.part.WTPart"
value="${param.oid}" />
</jca:getModel>
serviceName=
"com.ptc.windchill.enterprise.part.commands.PartDocServiceCommand"
methodName="getAssociatedDescribeDocuments" >
Example
customTable3.jsp
<%-->Get the Described By relation NmHTMLTable from the command<--%>
<jca:describeTable var="described" id=
"part.relatedPartsDescribedByCADDocuments.list" type="wt.epm.EPMDocument"
label="${describedByCADDocTableHeader}"
configurable="true">
<jca:describeColumn id="type_icon"/>
<jca:describeColumn id="number"/>
<jca:describeColumn id="CADName"/>
<jca:describeColumn id="version" />
<jca:describeColumn id="infoPageAction" />
<jca:describeColumn id="name"/>
<jca:describeColumn id="containerName"/>
<jca:describeColumn id="association"/>
<jca:describeColumn id="state"/>
<jca:describeColumn id="lastModified"/>
<jca:describeColumn id="nmActions">
<jca:setComponentProperty key="actionModel" value="EMPTY_ACTION_
MODEL"/>
</jca:describeColumn>
</jca:describeTable>
serviceName=
"com.ptc.windchill.enterprise.part.commands.PartDocServiceCommand"
methodName="getAssociatedCADDocuments" >
<jca:addServiceArgument type="wt.part.WTPart" value="${param.oid}"/>
</jca:getModel>
2. Click Browse and navigate to the MPMToolingTypeRB file, and then click
Open. The table displays the existing values.
Note
The MPMToolingTypeRB file is located on the path: Windchill/
codebase/com/ptc/windchill/mpml/resource
3. Click New to add a new entry in the table. Enter the Display Name and the Key.
For example, the Display Name and the Key can be Tool_New and tool_
new respectively. You can also add description and comments.
4. Select the Selectable checkbox to display the new enumerated type value in
the dropdown menu of the category.
5. Select the Default Value checkbox to set the new value as the default value. In
the table, the entry with the default value is displayed in bold.
Prerequisite Knowledge
• Java classes and concepts such as class extension.
• Xconf mechanism to create properties.
Solution
The identification of a WTPart as a supplier part is driven by data utility
configured for isSupplierPart selector. The out-of-the-box data utility is
com.ptc.windchill.enterprise.associativity.asb.dataUti
lities.PartSupplierStatusDataUtility
The data utility produces an integer value for any given object. The integer values
have following significance:
The UI layer consumes the integer value and marks the children of any supplier
part as gray out.
The registered data utility entry out of the box is as follows:
<Option serviceClass=
"com.ptc.windchill.enterprise.associativity.asb.dataUtilities.PartSup
plierStatusDataUtility"
requestor="java.lang.Object"
selector="isSupplierPart"
cardinality="duplicate"/>
Procedure
To set up an object initialization rule to specify a life cycle template for a new
part:
1. First, create the custom view and life cycle template that are to be used.
a. As a Site administrator, navigate to Site ▶ Utilities ▶ View Administration
and create a new view.
b. In the Product or Library context, navigate to Utilities ▶ Life Cycle Template
Administration and create a basic life cycle template. Alternatively, use
Save As on an existing template.
Note
Only Product and Library contexts that were created with the MPMLink
Product with Advanced Lifecycle Management application template
support this configuration.
2. Edit the MPMLink Part object initialization rule to specify the view and life
cycle templates created earlier.
a. From the Product or Library context, navigate to Utilities ▶ Object
Initialization Rules Administration.
b. Right-click on the MPMLink Part rule and select Download. Open the
downloaded file in a simple text or XML editing tool. The file contains the
following XML code:
<AttributeValues objType="wt.part.WTPart">
</AttributeValues>
c. Add the view and life cycle template names in a pair of argument tags. In
this example, the name of the view and lifecycle are:
<Arg>CustomViewName</Arg>
<Arg>CustomLifecycleName</Arg>
These lines must be added after the last argument tag. The following
example includes these tags.
<AttributeValues objType="wt.part.WTPart">
</AttributeValues>
The object initialization rule XML file must always have a single argument
for the default life cycle and exactly two arguments for each mapping to be
added: the view name and the life cycle template name. If the life cycle
name will not be localized, then the <Arg> argument tags containing
<?loc> localization strings can be omitted. Otherwise, add localization
argument tags for each.
d. Save the XML file to a local drive.
e. From the Object Initialization Rules page, right-click the MPMLink Part
rule and select Edit . The Edit Object Initialization Rule window opens.
From the XML File field, click Browse and select the edited XML file
stored on the local drive. Click OK.
3. Create a new part in the Product or Library to confirm that the object
initialization rule correctly applies the desired life cycle template when the
object is created with the specified view. In this procedure’s example, parts
created with the view “CustomViewName” will be assigned the
“CustomLifecycleName” lifecycle template.
For more information, see Manufacturing Life Cycles and Specifying Rules.
Problem Statement
You want to configure or implement logic to create and customize new
discrepancy types.
Intended Outcome
Users will be able to implement their custom discrepancy logic with the provided
framework. The logic allows detection and resolution of upstream changes and
provides guidelines to add new discrepancies.
Solution
Use the out of the box configuration and customization hooks to implement logic
for adding new discrepancies.
Prerequisite Knowledge
To perform this task, you must have an understanding of the following:
• Basic MPMLink and BOM structure
• Basic development involving Java
• Management of resource bundle file customizations
• Windchill xconfmanager and delegate concepts
Solution Elements
1. DiscrepancyType
The class DiscrepancyType represents the type of discrepancy. This class
is marked as supported and contains out of the box discrepancies.
This is a standard Windchill enumeration with its own rbInfo file
DiscrepancyTypeRB.rbInfo, which can be customized using out of the
box enumCustomize tool.
All the enumerations marked as selectable are shown in the BOM Transformer
interface in MPMLink. You can use the enumCustomize tool to update the
existing list of discrepancy types and add or remove the types.
</Service>
Note
The selector is the internal name of the discrepancy type.
4. Reconciliation Context
This is the main input for the reconciliation service. The responsible class is
ReconciliationContext. You can provide any custom input using the
addAdditionalParam method.
public void addAdditionalParam(String key, Object
value);
This map can be populated with a key or value which can be read in most of
the customization hooks across the flow of service as well as in
DiscrepancyDelegate. This allows for customization which can be
driven based on different inputs; for example, when performing different tasks
differently for client or server usage. Also, this allows the service or
customization to cache performance intensive information which can be
reused across different delegates.
5. Reconciliation Criteria
The class CriteriaType represents the criteria to compare the current
iteration of the upstream structure with the previous iteration. This class is
marked as supported and contains out of the box criteria types.
This is a standard Windchill enumeration with its own rbInfo file
CriteriaTypeRB.rbInfo which can be customized using the out of the
box enumCustomize tool.
AbstractCriteria is the base class used to find the previous item to be
compared with the current item for detecting discrepancies. The service uses
the previous item to build the previous path or structure information to detect
structure discrepancies.
6. Reconciliation Service
The main service interface to interact with the discrepancy model is
ReconciliationService. The service provides APIs to detect or resolve
Procedure
The procedure to include custom configuration or custom logic is given below:
1. Create a new CUSTOM_DISCREPANCY in
DiscrepancyTypeRB.rbInfo using enumCustomize tool.
2. Create a new delegate CustomDiscrepancyDelegate and add an entry
in the WT_HOME/codebase/com/ptc/windchill/
associativity/xconfs/
associativity.service.properties.xconf file.
<Option cardinality="singleton" selector="CUSTOM_DISCREPANCY"
requestor="null"
serviceClass=
"com.ptc.windchill.associativity.reconciliation.part.CustomDiscrepancyDe
legate"/>
Problem Statement
You want to configure or implement the following logic to manage BOM
transformation using automation:
• Transform new upstream BOM to a downstream BOM.
• Sync upstream BOM with an existing downstream BOM.
Background
MPMLink provides actions and business logic to transform upstream BOM into a
downstream BOM. However, end users perform most of the transformation
actions. These actions can be automated based on a specific configuration or logic.
For example, the transformation can be automated based on a change process or
an event.
Intended Outcome
You will be able to implement your logic and ensure that it is being used by the
template. The template can be automatically triggered during a change process or
other similar processes.
Solution
Use the out of the box configuration and customization hooks to implement your
logic.
Prerequisite Knowledge
To perform this task, you need to have an understanding of the following:
• Basic MPMLink and BOM structure
• Basic development involving Java
Solution Elements
The out of the box configuration for the main class that handles the template flow
is located in the <WT_HOME>/codebase/com/ptc/windchill/mpml/
xconfs/mpmlink.service.properties.xconf file.
The configuration is given below:
<Service context="default"
name=
"com.ptc.windchill.associativity.reconciliation.resolver.AbstractAddUsa
geResolver">
<Option cardinality="singleton" requestor="wt.part.WTPart"
serviceClass=
"com.ptc.windchill.mpml.reconciliation.resolver.MPMLinkAddedUsageDiscre
pancyResolver"/>
</Service>
Examples of configuring the property with the above keys are given below:
• Specifying the type:
com.ptc.windchill.associativity.reconciliation.addu
sage.wt.part.WTPart
• Specifying the type with the upstream and downstream view:
com.ptc.windchill.associativity.reconciliation.addu
sage.design.manfacturing.wt.part.WTPart
The system supports reading property for the usage and child in the same order of
priority. All the properties are supported for usage as well as child though it may
not be applicable in some cases.
For each of the property keys, you can define a list of key=value pairs. The
pairs are customizable and additional options can be added which will be available
in the delegates and can be handled using custom logic. The out of the box key
value pairs are given in the table:
Examples of configuring the property with the above keys are given below:
• <Property name=
"com.ptc.windchill.associativity.reconciliation.addu
sage.org.rnd.CustomPart" multivalued="," default=""/>
Procedure
Examples of Code-level Customizations
There are multiple options to perform code-level customizations. The flowchart
given below illustrates a high-level code for the out of the box template. Most of
the code blocks in the flowchart are customization hooks that allow you to write
your business specific logic for the flow.
To override the behavior for processing the children of a given node, override the
isValidForFurtherProcessing() method:
Problem Statement
Add your own logic for detection, verification, and resolver to configure the
delegate FlexibleRepresentationDiscrepancyDelegate.
Background
The flexible assembly discrepancy feature detects discrepancies in flexible
features between the current and the last equivalent iteration of upstream parts.
Solution
Use the out-of-the-box configuration and customization hooks to find the flexible
representation discrepancy.
Prerequisite Knowledge
To achieve the objective, you need to understand the following:
• Basic development involving Java.
• Windchill xconfmanager and delegate concepts.
Solution Elements
FlexibleRepresentationDiscrepancyDelegate: Class to define a
custom or default delegate. You can extend this class and create your own
delegate. After configuring the delegate, add an entry in the xconf file.
Here is an example of an out-of-the-box configuration. The xconf file for
configuration: associativity.service.properties.xconf, is located
at codebase\com\ptc\windchill\associativity\xconfs.
<Option cardinality="singleton" selector="FLEXIBLE_REPRESENTATION"
requestor="null" serviceClass="com.ptc.windchill.associativity.
reconciliation.part.FlexibleRepresentationDiscrepancyDelegate" />
Procedure
1. Create a new delegate, such as CustomQuickSearchQueryDelegate.
2. Add an entry about the delegate in the
BaseClient.service.properties.xconf file located at WT_
HOME/codebase/com/ptc/windchill/baseclient/xconf.
<!-- Custom ECNQuerySearch delegate-->
<Service context="default" name="com.ptc.windchill.
baseclient.server.delegate.QuickSearchQueryDelegate">
<Option cardinality="duplicate" requestor="null"
serviceClass="com.ptc.windchill.baseclient.server.delegate.
CustomQuickSearchQueryDelegate" selector="custom" />
</Service>
Problem Statement
Provide additional configuration to compare the paths between the upstream and
downstream structures based on custom logic when identifying discrepancies.
Background
The Resolve Consumption Discrepancies action provides the capability to fix
unresolved consumption links for a given downstream structure.
Intended Outcome
Display the desired custom discrepancy information in the Consumption
Discrepancy Report dialog box.
The following API provides additional hooks to add custom logic to match the
paths apart from the out-of-the-box logic for identifying discrepancy.
protected void
matchOnCustomLogic(Collection<AssociativePath> upPaths,
Collection<AssociativePath> downPaths,
HealConsumptionParams params, HealConsumptionReport
report) throws WTException
Problem Statement
Users want to display information that is not available by default in BOM
Transformer, such as equivalence network. They can do so by adding custom tabs
in the upstream and downstream structure.
Background
As a site customizer, you want the ability to create custom tabs in BOM
Transformer using JSP. An ideal scenario is to create custom JCA tables and add
the tables on the custom tabs.
Intended Outcome
The JSP file contents should be visible in the respective upstream and downstream
custom tabs.
In the given example, Custom Tab 1 shows the related documents in tables.
In the given example, Custom Tab 2 and Custom Tab 3 display the relevant
information.
Solution
Prerequisite Knowledge
To perform this task, you need to understand the following:
• Basic development involving JSP, JavaScript, and Custom taglibs.
• Management of customizations related to resource bundle files.
• Windchill xconfmanager concepts.
• Windchill folder structure.
downstreamCus downstreamCus
tomJsp3.jsp tomJsp1.jsp creates
Custom Tab 1,
downstreamCus downstreamCus
tomJsp4.jsp tomJsp2.jsp creates
downstreamCus Custom Tab 2, and so on.
tomJsp5.jsp
mpmlink.proper XCONF properties file XCONF file to specify
ties.xconf the properties for adding
JSPs in BOM
Transformer.
Runtime location: <WT_
HOME>/ codebase/
com/ptc/
windchill/mpml/
xconfs/
mpmlink.proper
ties.xconf
Procedure
Perform the following steps to add JSPs in BOM Transformer:
1. Copy the created JSP files to the location: Windchill/codebase/
netmarkets/jsp/mapsb.
Note
If you copy the contents of one JSP file to another, ensure that the IDs of the
tags in the JSP files are different. Otherwise, it can result in issues.
Background
The equivalence network delegate is introduced to customize the value displayed
in the Equivalence Network attribute.
For example, an Engine assembly has equivalent parts in the view: Design –
Manufacturing – Plant1 – Plant2 – Plant3. This path is displayed using the
Equivalence Network attribute. You can restrict the path to display the network
until Plant 2: Design – Manufacturing – Plant1 – Plant2. To do so, you need a
custom delegate.
Intended Outcome
Display the desired equivalence network in the part information page or in BOM
Transformer.
Solution
Use the out-of-the-box configuration and customization hooks to implement logic
to fetch the equivalence network.
Prerequisite Knowledge
To perform this task, you need to understand the following:
• Basic development involving Java.
• Windchill xconfmanager and delegate concepts.
Solution Elements
• Equivalence Network Delegate: Abstract class to define a custom or
default delegate. You can extend this class or
DefaultEquivalenceNetworkDelegate that follows.
• DefaultEquivalenceNetworkDelegate: Default implementation of
EquivalenceNetworkDelegate.
Note
The requestor is the internal name of object type.
Procedure
Perform the following steps to configure the equivalence network delegate:
1. Create a new delegate, such as
CustomEquivalenceNetworkDelegate.
2. Add an entry about the delegate in the
associativity.service.properties.xconf file at this location:
WT_HOME/codebase/com/ptc/windchill/associativity/
xconfs.
<!-- Equivalence Network delegate -->
<Service context="default" name=
"com.ptc.windchill.associativity.equivalence.EquivalenceNetworkDele
gate">
<Option cardinality="singleton" requestor="wt.part.WTPart"
serviceClass=
"com.ptc.windchill.associativity.equivalence.CustomEquivalenceNetwork
Delegate "/>
</Service>
3. Override the following methods in
CustomEquivalenceNetworkDelegate:
• public abstract NavigationCriteria
getNavigationCriteria(NavigationCriteria nc,
EquivalenceLink link, boolean fetchDownstream)
throws WTException;
Provides logic for the navigation criteria to search for parts.
Problem Statement
You want to export custom types of reports and add custom columns in reports.
Background
A manufacturing engineer may want to generate associative reports from the
upstream and downstream structures. This report can include equivalence or
occurrence information for the respective structure. This information is useful to
identify broken, out-of-date links between usages and occurrences.
You can customize the reporting feature to generate custom types of reports and
also add new columns in reports.
Intended Outcome
• The Report Types list in the Export Associative BOM Report window displays
the report type that you added.
• The exported report shows the columns that you added.
Solution
Use the out-of-the-box configuration and customization hooks to implement logic
to export reports.
Prerequisite Knowledge
To achieve the objective, you need to understand the following:
• Basic development involving Java.
• Windchill xconfmanager and delegate concepts.
• Using enumCustomize utility.
Solution Elements
• MPMLReportDelegate: Abstract class to define a custom or default
delegate. You can extend this class or extend the following classes as required.
• AssociativeBOMReportDelegate: Abstract class to use for the
associative structure.
• EquivalenceReportDelegate: Default implementation of
AssociativeBOMReportDelegate. Use this delegate to add
information related to equivalence status in the report.
• ConsumptionReportDelegate: Extends
EquivalenceReportDelegate to show information related to
occurrence status, such as occurrence status, reference designator, in the
report. You can extend this delegate to add more columns in the report.
• UsageConsumptionReportDelegate: Use this delegate to add
information related to usage status in the report.
Procedure
Suppose that you want to add information related to department data along with
the equivalence status in the report. You can create a delegate and extend
EquivalenceReportDelegate to do so.
Problem Statement
You want to associate an object that you are checking in with a change object of
your choice. To display custom search result for change objects, you need to
modify the search criteria or include additional filters.
Background
QuickSearchWidget helps to list autosuggested options when searching for a
change object. Use QuickSearchQueryDelegate to define the search query
to execute in QuickSearchwidget.
Intended Outcome
The search result displays the desired change objects based on the configuration
specified in QuickSearchQueryDelegate.
Prerequisite Knowledge
To achieve the objective, you need to understand the following:
• Basic development involving Java.
• Windchill xconfmanager and delegate concepts.
Solution Elements
• QuickSearchQueryDelegate: Interface to define a custom or default
delegate. You can extend this interface or the
DefaultQuickSearchQueryDelegate class that follows.
• DefaultQuickSearchQueryDelegate: Default implementation of
QuickSearchQueryDelegate.
An example of out-of-the-box configuration follows. The xconf file for
configuration: associativity.service.properties.xconf, is located
at codebase\com\ptc\windchill\associativity\xconfs.
<!-- ECNQuerySearch delegate-->
<Service context="default" name="com.ptc.windchill.baseclient.
server.delegate.QuickSearchQueryDelegate">
<Option cardinality="duplicate" requestor="null"
serviceClass="com.ptc.windchill.baseclient.server.delegate.
DefaultQuickSearchQueryDelegate" selector="default" />
</Service>
Procedure
1. Create a new delegate, such as CustomQuickSearchQueryDelegate.
2. Add an entry about the delegate in the
BaseClient.service.properties.xconf file located at WT_
HOME/codebase/com/ptc/windchill/baseclient/xconf.
<!-- Custom ECNQuerySearch delegate-->
<Service context="default" name="com.ptc.windchill.
baseclient.server.delegate.QuickSearchQueryDelegate">
<Option cardinality="duplicate" requestor="null"
serviceClass="com.ptc.windchill.baseclient.server.delegate.
CustomQuickSearchQueryDelegate" selector="custom" />
</Service>
Problem Statement
You want the object reference attributes to refer to objects of your choice. To
display custom search result for reference objects, you want to configure the
search action based on the following customization points:
• Modify the criteria for the search query.
• Add additional filters.
• Display custom attributes in search result.
• Refresh all or editable attributes.
Intended Outcome
The search result displays the desired reference objects based on the configuration
specified in ObjectReferenceAttributeSearchDelegate.
Solution
Use the out-of-the-box configuration and customization hooks to fetch the
reference objects.
Prerequisite Knowledge
To achieve the objective, you need to understand the following:
• Basic development involving Java.
• Windchill xconfmanager and delegate concepts.
Solution Elements
• ObjectReferenceAttributeSearchDelegate: Interface to define a
custom or default delegate. You can extend this interface or the
DefaultObjectReferenceAttributeSearchDelegate class that
follows.
• DefaultObjectReferenceAttributeSearchDelegate: Default
implementation of ObjectReferenceAttributeSearchDelegate.
An example of out-of-the-box configuration follows. The xconf file for
configuration: associativity.service.properties.xconf, is located
at codebase\com\ptc\windchill\associativity\xconfs.
<!-- ObjectReference attribute search delegate -->
<Service context="default" name="com.ptc.windchill.baseclient.
server.delegate.ObjectReferenceAttributeSearchDelegate">
<Option cardinality="duplicate" requestor="null" serviceClass=
"com.ptc.windchill.baseclient.server.delegate.
DefaultObjectReferenceAttributeSearchDelegate" selector="com.ptc.
Procedure
1. Create a new delegate, such as
CustomObjectReferenceAttributeSearchDelegate.
2. Add an entry about the delegate in the
BaseClient.service.properties.xconf file located at WT_
HOME/codebase/com/ptc/windchill/baseclient/xconf.
<Service context="default" name="com.ptc.windchill.baseclient.
server.delegate.ObjectReferenceAttributeSearchDelegate">
<Option cardinality="duplicate" requestor="null" serviceClass=
"com.ptc.windchill.baseclient.server.delegate.
CustomObjectReferenceAttributeSearchDelegate" selector="com.
ptc.windchill.enterprise.data.EnterpriseData|com.ptc.windchill.
enterprise.data.enterpriseData.PlantSpecificEnterpriseData|org.
rnd.Pune~alternateobjref" />
</Service>
Problem Statement
You want a postprocessing action to be executed after an object reference attribute
is saved, such as updating other attributes of the same object.
Background
Use ObjectReferenceAttributeSaveDelegate to specify the actions
to execute after the object reference attribute is saved. Out of the box, the delegate
does not execute any postprocessing actions
Intended Outcome
The specified action is executed after you save the attribute.
Solution
Prerequisite Knowledge
To achieve the objective, you need to understand the following:
Solution Elements
• ObjectReferenceAttributeSaveDelegate: Interface to define a
custom or default delegate. You can extend this interface or the
DefaultObjectReferenceAttributeSaveDelegate class that
follows.
• DefaultObjectReferenceAttributeSaveDelegate: Default
implementation of ObjectReferenceAttributeSaveDelegate.
An example of out-of-the-box configuration follows. The xconf file for
configuration: associativity.service.properties.xconf, is located
at codebase\com\ptc\windchill\associativity\xconfs.
<Service context="default" name="com.ptc.windchill.baseclient.
server.delegate.ObjectReferenceAttributeSaveDelegate">
<Option cardinality="duplicate" requestor="null" serviceClass=
"com.ptc.windchill.baseclient.server.delegate.
DefaultObjectReferenceAttributeSaveDelegate" selector="com.ptc.
windchill.enterprise.data.EnterpriseData|com.ptc.windchill.
enterprise.data.enterpriseData.PlantSpecificEnterpriseData|org.
rnd.Pune~alternateobjref" />
</Service>
Procedure
1. Create a new delegate, such as
CustomObjectReferenceAttributeSaveDelegate.
2. Add an entry about the delegate in the
BaseClient.service.properties.xconf file located at WT_
HOME/codebase/com/ptc/windchill/baseclient/xconf.
<Service context="default" name="com.ptc.windchill.baseclient.
server.delegate.ObjectReferenceAttributeSaveDelegate">
<Option cardinality="duplicate" requestor="null" serviceClass=
"com.ptc.windchill.baseclient.server.delegate.
CustomObjectReferenceAttributeSaveDelegate" selector="com.ptc.
windchill.enterprise.data.EnterpriseData|com.ptc.windchill.
enterprise.data.enterpriseData.PlantSpecificEnterpriseData|org.
rnd.Pune~alternateobjref" />
</Service>
com.ptc.arbortext.windchill.sapsb.tabVisibility
This property controls the visibility of tabs in the Service Associative Product
Structure Browser (SAPSB). This property is added by default to
SAPSB.properties.xconf. The following values are set to “true” by
default.
Value Tab
SAPSB.upstreamSideViz Visualization (upstream pane)
SAPSB.upstream.replace Replacements (upstream pane)
ments
SAPSB.upstream.documenta Documentation (upstream pane)
tion
SAPSB.upstream.equivalent Equivalent (upstream pane)
SAPSB.upstream.aum Alternate Units (upstream pane)
SAPSB.downstreamSideViz Visualization (downstream pane)
SAPSB.downstream.replace Replacements (downstream pane)
ments
SAPSB.downstream.documen Documentation (downstream pane)
tation
SAPSB.downstream.equiva Equivalent (downstream pane)
lent
SAPSB.downstream.aum Alternate Units (downstream pane)
Name
Show related smart collections on part info page.
Objective
Demonstrate customization guidelines for displaying related smart collections on
part information page.
Problem Statement
You want to display related smart collections on part information page.
Solution
Use customization hooks to implement logic for displaying related smart
collections on part information page.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic MPMLink and BOM structure
• Basic development involving Java
• Management of *-actions.xml and *-actionmodels.xml file
customizations
• Windchill JCA table builder
• OOTB smart collection create and edit
Solution Element
AccountabilityServiceImpl().getAccountabilityMaps(part)
— This API returns all smart collections that contain the input part (as a value) as
well as all smart collections that have the input part set as root context. All
versions of a smart collection found will be returned.
1. Configure new table builder which extends
AbstractComponentBuilder.
2. In the buildComponentData() of the table builder, acquire wtPart
content object from params and use new
AccountabilityServiceImpl().getAccountabilityMap
s(part) API to obtain the smart collections related with the part.
Objective
Provide customization guidelines for adding custom parameters in the URL
address of BOM Transformer.
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
• Basic knowledge of MPMLink and BOM structure
• Basic development involving Java
• The management of *-actions.xml, *-actionmodels.xml, and
*.xconf files customizations
Solution Elements
Perform the following steps to add custom parameters in the URL of BOM
Transformer:
1. Write a new custom delegate that extends
com.ptc.windchill.enterprise.associativity.asb.ser
ver.delegate.DefaultAddBrowserParametersDelegate
delegate and overrides Map<String, String>
@Override
protected Map<String, String> getAdditionlParamenters
(NmCommandBean commandBean, HttpServletRequest request) {
// Customization code
Map<String, String> additionlParamenters = super.
getAdditionlParamenters(commandBean, request);
additionlParamenters.put("param1", "value1");
return additionlParamenters;
}
}
2. Update the com/ptc/windchill/enterprise/associativity/
asb/xconf/asb.service.properties.xconf file for the entry of
AddBrowserParametersDelegate and change serviceClass to
newly added class. For example, using custom delegate
CustomAddBrowserParametersDelegate, the sample code is as
follows:
<Service context="default" name="com.ptc.windchill.
enterprise.associativity.asb.server.delegate.
AddBrowserParametersDelegate">
<Option cardinality="singleton" requestor="null" selector=
"mapsb" serviceClass="com.custom.delegate.
CustomAddBrowserParametersDelegate "/>
</Service>
Objective
Provide customization guidelines for merging a filter with a smart collection in
MASPB
Prerequisite Knowledge
To apply this best practice, you need to have an understanding of the following:
• Basic knowledge of MPMLink and BOM structure
• Basic development involving Java
• The management of *-actions.xml, *-actionmodels.xml, and
*.xconf files customizations
@Override
public NavigationCriteria mergeNC(NavigationCriteria
savedNc, NavigationCriteria clientNc) throws WTException {
// customization code to put filters or configuration
specification from savedNc to clienNC
return clientNc;
}
}
3. Update the xconf entry for a new class. For example,
CustomOpenAMInStructureBrowserDelegate.
4. Remove an entry for OpenAMInStructureBrowserDelegate delegate
in com/ptc/windchill/associativity/xconfs/
associativity.service.properties.xconf file.
The sample code is as follows:
<Service context="default" name="com.ptc.windchill.associativity.
delegate.OpenInStructureBrowserDelegate">
<Option cardinality="singleton" requestor="wt.facade.
persistedcollection.PersistedCollectionHolder" serviceClass="com.
ptc.windchill.associativity.delegate.
OpenMCInStructureBrowserDelegate"/>
Delegates
As a Windchill administrator, you can also specify a company-specific default
value for some of these attributes, as well as a list of optional values that are
applicable to the selected downstream object(s). You do this by either modifying a
standard delegate, or by replacing the standard delegate with your own custom
delegate (Type and View attributes only), as explained in the following procedure.
Caution
Modifying property files can have unexpected consequences if done
improperly.
Preferences
As a user, you can control the default value displayed in the panel for this attribute
by setting one or more of the following preferences within the Windchill
Preference Management utility.
Delegate
As a Windchill administrator, you can also specify a company-specific default
value for the View attribute, as well as a list of optional values that are applicable
to selected downstream object(s). You do this by either modifying the standard
delegate, or by replacing the standard delegate with your own custom delegate
(Type and View attributes only), as explained in the following procedure.
Output: • New
Downstream
• Default view per Branch Variant
selected object.
• Duplicate
• Option list of
• Replace with
applicable views per
New
selected object
• Upstream
Filter
Properties
• Downstream
Filter
Properties
• Insert New
Part
• Insert Multiple
New
• Extend BOM
Equivalence
• Assemble as
New Part/
Branch
Note
In this example the name of the custom JSP-based page is customReport.jsp
Note
As of release 10.0 Windchill no longer uses Rational Rose for modeling.
Note
Code examples in this chapter have been reformatted for presentation purposes
and, therefore, may contain line number, hidden editing characters (such as
tabs and end-of-line characters) and extraneous spaces. If you cut and paste
code from this manual, check for these characters and remove them before
attempting to use the example in your application.
Jython
Jython is a Java implementation of the popular Python programming language.
Jython is used in this chapter to provide working code that demonstrates the
examples in “real world” scenarios. Jython’s dynamic nature makes it particularly
attractive (over Java programs) because its interpreter facilitates interaction and
exploration that simply is not possible with compiled code and a debugger.
Additionally, while Jython is a Python implementation (on top of Java), the syntax
is readily familiar to Java programmers and instantly translatable.
Note
The examples using Jython assume a Windchill CLASSPATH, which is
readily available if run from inside a Windchill shell (which can be started by
invoking <load point>/Windchill/bin shell).
Compilation
Compilation is covered extensively in the JavaDoc for the
com.ptc.windchill.annotations.metadata package. However, the
SimpleExample customization can be compiled and incorporated by executing
the following steps:
1. cd to your load point (for example, /opt/ptc/Windchill)
2. Start a Windchill shell by invoking bin/windchill shell
3. Create the src/com/acme/example directory via mkdir -p src/com/
acme/example
4. Create SimpleExample.java in this directory and give it the contents of
the example above
5. Compile the example with ant -f bin/tools.xml class
-Dclass.includes=com/acme/example/* (note that this command
must be executed in the load point directory)
6. Generate SQL scripts with ant -f bin/tools.xml sql_script
-Dgen.input=com.acme.example.*
7. Find the create_SimpleExample_Table.sql SQL script (it will be
somewhere in db) and load it
8. Repeat for create_SimpleExample_Index.sql.
9. Start/restart the MethodServer
Jython can be used to quickly validate the example, as shown in Listing 5.
Listing 5: Persisting SimpleExample
01 from wt.fc import PersistenceHelper
02 from com.acme.example import SimpleExample
03
Modeling Columns
GenAsPersistable and GenAsBinaryLink provide three mechanisms for
specifying database columns:
1. properties (an array of GeneratedPropertys) represent strings,
numbers, booleans, etc.
2. foreignKeys (an array of GeneratedForeignKeys) reference other
persistent objects (and are stored as a classname/key pair)
3. roleA/roleB (GenAsBinaryLink only) are a special form of a foreign
key used in associations
Additionally derivedProperties (an array of DerivedPropertys)
provide convenience accessors to properties and foreign keys.
It is sometimes useful to collect a set of properties together into its own class
which can then be managed as an entity and aggregated into a persistent object.
The GenAsObjectMappable annotation exists for this purpose and is widely
utilized by Windchill “cookies”. When a GenAsObjectMappable-annotated
class is specified as the type for a GeneratedProperty, all its properties
become columns in the owning class’s table. To prevent name-collisions, the
names are “mangled” using a character/number pattern dictated by an arcane
algorithm; it is this mangling that accounts for the “idA3” in
idA3containerReference and the mapping of
Persistable.thePersistInfo.theObjectIdentifier.id to
idA2A2.
GeneratedProperty
An example of GeneratedProperty in our SimpleExample (name, which
is required and of type String) has already been shown.
GeneratedProperty supports a number of annotation members for
controlling generation and behavior. See the Windchill JavaDoc for more
information.
GeneratedForeignKey
A foreign key was not modeled, it was inherited from WTContained.
Listing 9: container definition snippet
01 @GeneratedForeignKey(name="ContainerLink",
02 foreignKeyRole=@ForeignKeyRole(name="container",
type=wt.inf.container.WTContainer.class, referenceType=
wt.inf.
container.WTContainerRef.class, supportedAPI=
SupportedAPI.PRIVATE,
03 constraints=@PropertyConstraints(required=true)),
GeneratedRole
The GeneratedRole annotation is used to describe the role A and B of a
GenAsBinaryLink, which we saw earlier in SimpleExampleLink. Roles
can be thought of as special foreign keys associating the link with two persistables
(and have the same inheritance capabilities as foreign keys). Whereas foreign keys
are applicable only when the cardinality of the associated role is 0-1 and where the
association requires no additional data (properties), binary links are applicable
when the association is many-to-many, when the association carries properties, or
when the association would otherwise be persisted on a PTC business object
(since you cannot alter existing PTC classes).
DerivedProperties
Derived properties aren’t themselves persisted, but they do provide convenience
accessors (getters, setters, and query constants) to persisted properties that would
otherwise be buried in cookies or across foreign key references. Let’s say you
have a field c which is buried inside a cookie b which is itself buried inside a
cookie a which is a property of our current class.
We could access it using this.getA().getB().getC(), being careful to
handle possible NullPointerExceptions should the cookies not be
initialized. Better yet, we could just add this derived property to our class and let
everything (including the handling of NullPointerException) be handled
for us.
Listing 10: a.b.c derived property
@DerivedProperty(name="c", derivedFrom="a.b.c")
GenAsUnPersistable “tables”
All classes recognized as being mapped to database tables must extend
wt.fc.Persistable. The GenAsPersistable-generated “_” class
automatically handles this for you; the GenAsBinaryLink-generated “_” class
achieves this by implementing wt.fc.BinaryLink, which extends
Persistable.
When modeling interfaces to be implemented by persistent classes, you will
typically use these annotations to describe the columns (properties, foreign keys,
and roles) you’ll ultimately want the implementing (concrete) classes to represent
as columns. Windchill’s domain interfaces employ this strategy, allowing you to
simply implement a bunch of interfaces to acquire important business logic like
work-in-progress (Workable) lifecycle management (LifeCycleManaged),
and so on.
You must annotate an interface if you want implementing classes to
(automatically) persist the interface’s properties. However, not every interface is
always intended to be implemented only by persistent classes. In some (exceeding
rare) cases, an interface may be implemented by persistent classes (necessitating
that the interface be annotated so its data can be persisted) and by non-persistent
classes (for which GenAsPersistable and GenAsBinaryLink’s ensuring
that the class ends up being Persistable is a problem). In these cases, you can
use the GenAsUnPersistable annotation to bridge the gap: any persistent
implementer will automatically treat the interface as though it were persistent,
while non-persistent implementers won’t get persistence foisted on them.
It should be noted that you’ll likely want your non-persistent classes to be
annotated with GenAsUnPersistable to get the same generation benefits as
its persistent cousins do, but this is not necessary. Additionally, since
externalization logic comes “for free”, you may wish to utilize this annotation in
cases where the class is to be “persisted” as a BLOB , since RMI externalization is
employed when blobbing instances. Here, “persisted as a BLOB” means that the
entire class will be stored in a BLOB column inside a persisted class’s table.
BLOBing an object is almost never recommended because it’s easy to overlook
the complexities of reading the BLOB back out, especially if the class has
changed since the instance was put in. Note that if you wish to store as a BLOB
any class implementing wt.fc.NetFactor, you must make that class
wt.util.Evolvable.
GenAsEnueratedType columns
Windchill provides support for modeling a discrete, localizable set of strings. Let’s
say you want to store computer models in Windchill and wanted to categorize
them as being either a desktop, laptop, or server. You could do this as
follows:
The class follows the general format established previously: an annotated class
that extends it’s (generated) “_” class. Classes annotated by
GenAsEnumeratedType will ultimately extend wt.fc.EnumeratedType
and, as can be seen, a number of methods are generated for you. Among them are
to<X>(String) and get<X>Default(), where X is the name of our class
(to see a complete listing, invoke javap com.acme.example._
ComputerType).
Lines 7-9 (of Listing 12) consist of constant declarations which rely on the
toComputerType(...) API to produce instances of the enumerated type.
Note that these entries must be present in the corresponding rbInfo file, which
GenAsPrimitiveType columns
If you look at the JavaDoc for wt.fc.EnumeratedType. you will see that
EnumeratedType is annotated with GenAsPrimitiveType. Also, the
single argument to the annotation is String.class.
The GenAsPrimitiveType annotation is a simple annotation, requiring a
single value: the “primitive” type the annotated class reduces to (for persistence
and serialization). You will likely never use it, but it exists when you want to build
a class (logic) around what is otherwise a pretty boring field. If you do use it, you
not only need to specify the type to reduce this class to as part of the annotation,
you also need to provide a constructor accepting the primitive type and a <type-
in-lower-case>Value() method to return the current value.
For more information, refer to the annotation’s JavaDoc.
Note
The GenAsDatastoreSequence is one of four GenAsDatastore
annotations.
Messages
Localizing class names and properties is not sufficient. Everything you wish to
communicate to users should be localized (note: a developer is not, necessarily, a
user). The rbInfo format is used for enumerated types as well as classes and
their properties. For general messages (typically included in exception or status
messages reported by services), Java source/class files ultimately extending
java.util.ListResourceBundle are utilized. As the contract for
ListResourceBundle is arcane, we’ll utilize WTListResourceBundle,
which is more declarative. An example:
Listing 24: exampleResource.java
01 package com.acme.example;
02
03 import wt.util.resource.*;
04
05 /** This example blatantly plagiarized from the JavaDoc. **/
06 @RBUUID("com.acme.example.exampleResource")
07 public class exampleResource extends WTListResourceBundle {
08 @RBEntry("This is the localized text with a single
substitution: \"{0}\".")
09 @RBComment("An example entry.")
10 @RBArgComment0("Any string...")
11 public static final String EXAMPLE_STRING = "0";
12 }
The first call will produce This is the localized text with a single
substitution: ‘‘substitution’’. and the second will raise (throw) an
exception with the message wt.util.WTException:
2203
The EnumeratedType Class
EnumeratedType represents a type whose possible values are constrained to a
set (as defined in a resource).
value
The internal value, which is persisted.
display
The localizable display text.
comment
An optional comment describing the value.
order
Provides an explicit sort order for the value.
defaultValue
Specifies the value that is the default value for the type.
selectable
Specifies if the value should be allowed to be selected.
• The constructors for EnumeratedTypes are protected so that instances can
only be constructed internally. The data needed for construction is obtained
from a resource and used to construct the instances in the static initializer.
• getValueSet() returns the set of possible values for the class, where the
possible values are instances of the class.
• toString() returns the internal value, which will be persisted. This follows
the pattern of primitive wrappers provided by Sun. This means toString() is
import com.ptc.windchill.annotations.metadata.
GenAsEnumeratedType;
@GenAsEnumeratedType
public class MySize extends _ MySize {
static final long serialVersionUID = 1;
}
2. Optionally, code any desired programmatic constants in MySize.java. For
example:
public static final State SMALL = toMySize("sm");
3. . Create its companion resource info file. For MySize, it will be named
MySizeRB.rbInfo. See details below.
The first line classifies the resource info and should never be changed. The values
of the second two lines can be changed by the owner of the package, if the file
should not be customized and if the file is deprecated.
med.value=Medium
med.order=20
sm.value=Small
sm.order=10
If the order properties are not defined, the options will be displayed in alphabetical
order, using the locale specific display value. One of the entries can have
defaultValue set to true. For example, the attributes for the "sm" value could
be as follows:
sm.value=Small
sm.shortDescription=Small Comment
sm.order=10
sm.defaultValue=true
The above script is a convenience wrapper for the bundle target in the bin/
tools.xml Ant script. To see all the options available for direct use of the
bundle target, use the following command:
ant -f bin/tools.xml bundle.help
For information on locales, and codes for languages and countries, see the
java.util.Locale class entry in your installed Windchill Javadoc.
The one caveat with using extended EnumeratedType instances is that, if concrete
types are used in the model, they are the only types that can be read back from the
database. Using the example in the preceding figure, this means that other
subclasses of MySize can be assigned to the size attribute of MyItem, and they
can be stored in the database, but they can be read out only as instances of the
types that are modeled.
This limitation would not apply if MySize were an abstract class. When an
abstract class is modeled, the runtime type information is stored in the database
along with the instance information. Therefore, the exact type and instance can be
reconstructed when reading it back from the database.
Note
The Type and Attribute Management utility is now the one and only
configuration point for "default values" shown in the UI. For more information
see the “Default Values Tab” online help topic in the Windchill Help Center.
The remainder of this section describes how to start the utility. For specific
instructions on its usage, see the online help available when you start the utility.
To see the changes you have made after using the utility, perform the following
steps:
1. Restart the method server.
2. Rebuild all of the client jar files so clients can access the new values.
3. Rebuild all of the client jar files so clients can access the new values.
4. Restart any Java clients. (HTML clients access the new values as soon as their
pages are refreshed from the server.)
Scope/Applicability/Assumptions
This capability applies to string attributes defined in the Type and Attribute
Management utility.
Intended Outcome
With this solution, you can constrain an attribute to an enumerated list of values
that comes from an external source. You can control the following:
• Localization of the values
• Sort order of the values
• Selectability of the values
• Any trigger condition to ensure the enumeration is always up to date
Solution
Implement an EnumerationInfoProvider to supply the enumerated list and
configure a constraint in the Type and Attribute Management utility to use your
EnumerationInfoProvider.
Prerequisite Knowledge
To achieve this objective, you need to have an understanding of the following:
• Adding constraints to an attribute in the Type and Attribute Management utility.
• How to extract the required enumeration values from your external source.
Sample
public EnumerationInfo getEnumerationInfo() {
EnumerationInfo enumerationInfo = new EnumerationInfo();
enumerationInfo.setNonLocalizableProperty(EnumerationInfo.
AUTO_SORT,
Boolean.TRUE);
enumerationInfo.setNonLocalizableProperty(EnumerationInfo.
DEFAULT_LOCALE,
Locale.EN_US);
return enumerationInfo;
}
An EnumerationInfo contains a collection of EnumerationEntryInfo
data structures. The EnumerationEntryInfo data structure supports two
non-localizable and one localizable property that you can use to customize the
behavior of your enumeration. Localizable properties can have distinct values set
of any number of different locales.
Sample
Set<EnumerationEntryInfo> enumEntryInfos =
int sortOrder = …;
Boolean selectable = …;
enumEntryInfo.setNonLocalizableProperty(EnumerationEntryInfo.
SORT_ORDER,
sortOrder);
enumEntryInfo.setNonLocalizableProperty(EnumerationEntryInfo.
SELECTABLE,
selectable);
Locale locale = …;
String displayName = …;
enumEntryInfo.setLocalizableProperty(EnumerationEntryInfo.
DISPLAY_NAME,
locale, displayName); }
Customization Points
• Customization Points - EnumerationInfo
Edit the JNDI adapter which is configured for the LDAP that contains the
additional attributes you want mapped to the user.
In the Additional Properties section of the JNDI adapter properties page, add
the property
<service.name>.windchill.mapping.user.attributes and
enter the attributes (comma separated) you want mapped as values for this
property. The <service.name> is the name of the adapter whose
properties you are modifying. If you chose to replace windchill with either
the name you provided for the web application, or any other name, then you
can add the property “wt.org.webAppName” to wt.properties and
provide the name you intend to use.
2. Open the LogicalAttributes.xml file from the <Windchill>\
codebase directory. Search for any definition of the WTUser class name
and append definitions for the attributes you created in step 1 to this section.
For example, for an attribute name “citizenship” the definition is shown below.
Make sure the value in the LogicalForm tag is the same as the attribute you
defined in step 1. The attributes are case-sensitive.
<Property>
<LogicalForm>citizenship</LogicalForm>
<ExternalForm>SCA|citizenship.key</ExternalForm>
</Property>
3. Add additional information on each of these attributes and the corresponding
Server Calculated Attribute Function (SCAF) that needs to be invoked to
retrieve the values of these attributes, into a resource bundle that is supported
for customization.
For example, modify the orgModelRB.rbInfo file in the
<Windchill>\src\wt\org directory and add entries similar to the
following:
WCTYPE|wt.org.WTUser~SCA|citizenship.key.value=Citizenship
WCTYPE|wt.org.WTUser~SCA|citizenship.key.abbreviatedDisplay=
Citizenship
WCTYPE|wt.org.WTUser~SCA|citizenship.key.dataType=java.lang.String
WCTYPE|wt.org.WTUser~SCA|citizenship.key.serverFunction=
com.ptc.core.foundation.org.server.impl.SACFLdapAttributeContainerFunc
tion
Note
The value of serverFunction should remain the same as the one
provided above, unless you write your own SCAF function. In addition if
the attribute was defined as a Boolean in step 1, then key.dataType
should be java.lang.Boolean. Do not change the type in
key.serverFunction. This must always be a String type.
7. Run the following command from a Windchill shell to rebuild the client jars.
ant -f codebase/MakeJar.xml
8. Delete the content from <WT_HOME>\Tomcat\instances directory.
9. Restart Windchill.
10. Navigate to the Site ▶ Utilities ▶ Type and Attribute Management. and create
new alias attributes for the attributes defined in step 2 for the User type.
• Verify the value for Internal Name matches the name provided in the
LogicalForm tag in step 2.
• Select the corresponding type in the next screen depending on whether the
attribute in ldap that you are mapping to, is a String or a Boolean.
• On the following screen provide a display name. This can be anything.
This controls what displays on the layout to which these attributes will be
added.
• In the Mapping field, provide the value that matches the ExternalForm
tag in step 2.
11. After the attributes are created, you can add them to the Information Page
layout. By default these additional attributes will also appear on the Simplified
For example:
ant -f bin/tools.xml class -Dclass.includes=*.java -Dclass.source=
<Windchill>\prog_examples\principal\user\validators
Note
One validator must be written for each attribute that should be hidden.
Edit the JNDI adapter which is configured for the LDAP that contains the
additional attributes you want mapped to the group.
In the Additional Properties section of the JNDI adapter properties page, add
the property
<service.name>.windchill.mapping.group.attributes and
enter the attributes (comma separated) you want mapped as values for this
property. The <service.name> is the name of the adapter whose
properties you are modifying. If you chose to replace windchill with either
the name you provided for the web application, or any other name, then you
can add the property “wt.org.webAppName” to wt.properties and
provide the name you intend to use.
2. Open the LogicalAttributes.xml file from the <Windchill>\
codebase directory. Search for any definition of the WTGroup class name
and append definitions for the attributes you created in step 1 to this section. If
one does not exist, you must create a new definition for one.
For example, for an attribute name “CreateDate” the definition is shown
below. Make sure the value in the LogicalForm tag is the same as the
attribute you defined in step 1. The attributes are case-sensitive.
<Property>
<LogicalForm>CreateDate</LogicalForm>
<ExternalForm>SCA|CreateDate.key</ExternalForm>
</Property>
3. Add additional information on each of these attributes and the corresponding
Server Calculated Attribute Function (SCAF) that needs to be invoked to
retrieve the values of these attributes, into a resource bundle that is supported
for customization.
For example, modify the orgModelRB.rbInfo file in the
<Windchill>\src\wt\org directory and add entries similar to the
following:
WCTYPE|wt.org.WTGroup~SCA|CreateDate.key.value=CreateDate
WCTYPE|wt.org.WTGroup~SCA|CreateDate.key.abbreviatedDisplay=CreateDate
WCTYPE|wt.org.WTGroup~SCA|CreateDate.key.dataType=java.lang.String
WCTYPE|wt.org.WTGroup~SCA|CreateDate.key.serverFunction=
com.ptc.core.foundation.org.server.impl.SACFLdapAttributeContainerFunc
tion
Note
The value of serverFunction should remain the same as the one
provided above, unless you write your own SCAF function. In addition if
the attribute was defined as a Boolean in step 1, then key.dataType
should be java.lang.Boolean. Do not change the type in
key.serverFunction. This must always be a String type.
7. Run the following command from a Windchill shell to rebuild the client jars.
ant -f codebase/MakeJar.xml
8. Delete the work directory from the <Windchill>\Tomcat directory.
9. Restart Windchill.
10. Navigate to the Site ▶ Utilities ▶ Type and Attribute Management. and create
new alias attributes for the attributes defined in step 2 for the Group type.
• Verify the value for Internal Name matches the name provided in the
LogicalForm tag in step 2.
• Select the corresponding type in the next screen depending on whether the
attribute in ldap that you are mapping to, is a String or a Boolean.
• On the following screen provide a display name. This can be anything.
This controls what displays on the layout to which these attributes will be
added.
• In the Mapping field, provide the value that matches the ExternalForm
tag in step 2.
11. After the attributes are created, you can add them to the Information Page
layout. By default, these additional attributes will also appear on the
For example:
ant -f bin/tools.xml class -Dclass.includes=*.java -Dclass.source=
<Windchill>\prog_examples\principal\group\validators
Note
One validator must be written for each attribute that should be hidden.
2229
Creating a System Configuration
Collector Plugin
You want to create a new plugin for use with the System Configuration Collector
UI in Windchill that will perform some function that the available plugin lack.
The plugin will likely assist you in debugging Windchill configuration,
installation and runtime issues.
Background
The System Configuration Collector is a Windchill UI page, currently accessed
via the UI navigation path of Site ▶ Utilities ▶ System Configuration Collector when
logged into Windchill as a user from the system administrators LDAP group. The
UI provides functionality that system administrators can use to collect, save and
also send Windchill system and configuration information to both local system
and remote systems, including PTC Technical Support.
The directive of the System Configuration Collector is one that allows a user to
gather as much appropriate information at one time regarding a Windchill system.
The information collected is targeted to consumers who can then more readily use
the information to diagnose any potential system and/or configuration issue with
the Windchill instance.
On the System Configuration Collector page the system administrator can select
categories of problems, such as Performance and/or Runtime related issues. A
number of corresponding plugins will then execute. The list of plugins that will
execute can be seen by expanding each respective category root tree node on the
UI. Each plugin collects a discrete set of about the current Windchill system and
configuration. For example, some plugins collect information such as Windchill
Method Server logs, xconf properties files, JMX Mbean configuration information
and database information.
The plugins are the discrete means to accomplish a task for the System
Configuration Collector categories. These plugins can be designed to accomplish
any task that can be done through Java, including executing SQL and QML
scripts, java command utilities (those which include a main() method) and
Windchill Windu tasks.
The plugins comprise a set of software operations for one or more categories that
adds specific capabilities to the System Configuration Collector. The System
Configuration Collector was designed using plugin architecture such that the
functionality provided could be customized by PTC R&D, PTC Global Services,
PTC Technical Support and PTC customers. The plugin architecture is one that
allows a developer to extend and add new functionality to the System
Configuration Collector on a live Windchill system. Therefore, there is no need to
restart the Windchill servers for the new plugin to be recognized by the System
Configuration Collector. The plugin architecture allows for immediate use of the
developed plugin.
Scope/Applicability/Assumptions
The scope is restricted to the System Configuration Collector UI page and creating
plugins that operate on that page.
Assume you have an issue with a Windchill system that you must diagnose and no
current plugin provides the functionality you need to assist you in diagnosing the
issue.
Assume you want to extend the functionality of an existing plugin.
Intended Outcome
Once a plugin is properly designed, created and deployed in Windchill it can be
immediately used with the System Configuration Collector page. The plugin will
then execute whatever functionality it was designed to do to assist you in your
diagnosis.
After creating and deploying a plugin, refreshing the System Configuration
Collector UI will allow a user to make use of the deployed plugin. In the
screenshot below, the plugin has been added to the user defined “Custom Plugins”
category. This category only contains the custom created plugin “Tomcat Property
Config File” For more information see the section “Sample Code”.
Solution
Design, develop, deploy and execute a custom plugin with the System
Configuration Collector UI or a JMX Console.
Prerequisite Knowledge
To apply this solution, you need to have an understanding of the following:
• Basic development using Java – For developing plugins
Solution Elements
Element Type Description
As seen above, all plugins implement the PluginMBean interface and, eventually,
extend the AbstractPlugin class. A custom plugin can make use of the plugin
hierarchy and the functionality provided by any of the abstract classes.
@Override
public Map<String, Object> collect(String topicIdentifier,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct
Map
return null;
}
Here the constructor has been expanded to include a private method that
initializes all the plugin attributes including the MBean values that are
exposed.
This will be our reference to where our localized Java strings reside. Our
CustomPlugin can then make use of this reference to retrieve the localized
values. The refactored setDisplayName(string) and setDescription(string)
methods become:
// set the localized plugin display name
Limitations
Plugins used on the System Configuration Collector or used as MBeans can be
quite powerful. They can be used to collect files, directories, properties as well as
execute java classes, windu tasks, scripts, and gather database information.
Currently, the plugin execution is limited to SQL and QML scripts, WinDU tasks
and Java code.
Sample Code
CustomPlugin.java
package com.ptc.customersupport.mbeans.plugins;
import java.util.Map;
import java.util.ResourceBundle;
import javax.management.NotCompliantMBeanException;
import wt.jmx.core.MBeanUtilities;
import wt.log4j.LogR;
import com.ptc.customersupport.mbeans.AbstractPlugin;
import com.ptc.customersupport.mbeans.PluginMBean;
import com.ptc.customersupport.mbeans.PluginType;
public class CustomPlugin extends AbstractPlugin implements
PluginMBean {
@Override
public Map<String, Object> collect(final long callNumber,
final long maxAgeInDays,final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
@Override
public Map<String, Object> collect(String topicIdentifier,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
// TODO Do actual collection work and return correct Map
return null;
}
CustomPluginResource.java
package com.ptc.customersupport.mbeans.plugins;
import wt.util.resource.RBEntry;
import wt.util.resource.RBUUID;
import wt.util.resource.WTListResourceBundle;
@RBUUID("com.ptc.customersupport.mbeans.plugins.
CustomPluginResource")
public class CustomPluginResource extends WTListResourceBundle{
import java.util.Map;
import javax.management.NotCompliantMBeanException;
import wt.log4j.LogR;
import com.ptc.customersupport.mbeans.PluginType;
import com.ptc.customersupport.mbeans.plugins.GatherFilePlugin;
/**
* A sample Plugin that gathers the Tomcat config.properties file.
* The location of this file is controlled by the location of
* Tomcat on an installed system. Generally, this location is
* <Windchill>/tomcat/config.properties. However, there exists a
* wt.property which points to where the tomcat instance is
* installed. This property is installed.Product.location.Tomcat,
* and it is used to build a tokenized path to the location of the
* config.properties file.
* <BR><BR>
* This class extends the
* {@link com.ptc.customersupport.mbeans.files.GatherFilePlugin
* GatherFilePlugin} which is used to provide functionality that
is
* already implemented that this Plugin can rely upon for default
* behavior. Most plugins will be able to make use of existing
* Abstract plugin classes for much of their behavior and method
* implementations. See the
* {@link com.ptc.customersupport.mbeans.files.GatherFilePlugin
* GatherFilePlugin} for more infomration on the parent class of
* this Plugin and it's methods.
* <BR><BR>
*/
public class TomcatConfigPropertiesPlugin extends GatherFilePlugin
{
/*
* Optionally provide some form of localization for plugin
strings.
*
* In order to localize the values like name, description,
* and version, follow these steps:
*
/**
* Default constructor that sets all the required values.
*/
public TomcatConfigPropertiesPlugin() throws
NotCompliantMBeanException {
/*
* The operator call to super() allows the
* TomcatConfigPropertiesPlugin to rely on the parent
class for
* much of the Plugin initialization. This call will set
* default values which are later overridden as necessary.
This
* also sets up and initializes this Plugin as a
SelfAwareMBean
* as the inheritance hierarchy eventually reaches
* AbstractPlugin.
*/
super();
/*
* This method call is simply for convenience of setting
* all the Plugin values in one place that we are
* overriding the default values for which were set when
/**
* Initializes all the Plugin values for this specific Plugin.
* Those values which were initially set by parent classes are
* overidden.
*/
private void initializeMBeanAttributes() {
// Log a debug message that the Plugin is being
initialized.
if (logger.isDebugEnabled()) {
logger.debug("Initializing " + TCP_PLUGIN_NAME + "" +
" Plugin.");
}
/*
* Set the attribute values that are common to all
Plugins,
* regardless of the PluginType.
*/
// The name that will be used for this Plugin.
setDisplayName(TCP_PLUGIN_NAME);
// The description that will be displayed for this Plugin.
setDescription(TCP_PLUGIN_DESCRIPTION);
// Set the MBean ObjectName.
setMBeanName("TomcatConfigProperties");
/*
* Set the PluginType value. This will control where the
* data is collected to in terms of directory structure.
*/
setPluginType(PluginType.PROPERTY);
// Set the Plugin version information.
setPluginVersion("1.0");
/*
* Set the file name that we want to collect. This value
* overrides the default value set by the parent. The
* GatherFilePluginMBean Interface of the parent class
* specifies this method must be implemented. Since we
* are extending the parent class and want to collect a
* specific file (not the default file the parent
specifies)
* we override the value and set it to the location:
* $(installedProduct.location.Tomcat)$(dir.sep)
* config.properties
*
* This is a tokenized wt.property value. When the
* collection framework operates on this Plugin, these
/**
* Override the collect methods as needed. Incidentally, this
* Plugin does not dictate the collect(...) methods be
* overridden. The implementation of this method is actually
* the same as the parent implementation. However, for clarity
* of the example the collect(...) methods are shown.
*/
@Override
public Map<String, Object> collect(final long callNumber,
final long maxAgeInDays, final long minAgeInDays,
final String pathTimeStamp) {
/*
* Here we call the collectData(...) method of
AbstractPlugin
* which will handle the actual collecting of the file
* specified as the first parameter. Here the first
parameter
* is returned by the getFileName() method of the parent
* class.
*
* The collectData method sets up and hides all the
complexity
* of using the collection framework and allows a
developer to
* avoid implementing a specific collect(...)
implementation.
*
* However, there are instances when certain Plugins
require
* specific collect(...) method behavior, these instances
* are usually reserved for very advanced Plugins.
*/
return collectData(getFileName(), callNumber,
maxAgeInDays,
minAgeInDays, pathTimeStamp);
}
com.ptc.customersupport.mbeans package
This Java package contains the AbstractPlugin and PluginMBean
interface. It also contains additional utility classes that can be utilized in creating
plugins such as the PluginType.java and PluginUtilities.java.
com.ptc.customersupport.mbeans.plugin package
This Java package contains many of the abstract classes seen in the UML diagram
and discussed in Solution Elements. This package includes
com.ptc.customersupport.mbeans.plugin.logs package
This Java package contains concrete plugin implementations that are of
PluginType logs. These plugins are generally responsible for collecting log
files. Log4jFilesPlugin, WindchillLogsPlugin and
WDSLogsPlugin are examples that vary in complexity.
com.ptc.customersupport.mbeans.plugin.misc package
This Java package contains concrete plugin implementations that are of
PluginType misc. These plugins are generally responsible for collecting
miscellaneous information. UpgradeFolderPlugin,
MigrationReportsFolderPlugin and WtSafeAreaFolderPlugin
are examples that vary in complexity.
com.ptc.customersupport.mbeans.plugin.properties package
This Java package contains concrete plugin implementations that are of
PluginType properties. These plugins are generally responsible for collecting
properties files. DbPropertiesPlugin, DeclarationsXconfPlugin
and IePropertiesPlugin are examples that vary in complexity.
com.ptc.customersupport.mbeans.plugin.third package
This Java package contains concrete plugin implementations that are of
PluginType third. These plugins are generally responsible for collecting third
party product information. ApacheConfFolderPlugin,
ApacheLogsPlugin and CogStartupXmlPlugin are examples that vary
in complexity.
com.ptc.customersupport.mbeans.plugin.util package
This Java package contains concrete plugin implementations that are of
PluginType util. These plugins are generally responsible for collecting utility
information. GatherInfoScriptPlugin, MBeanDumpPlugin and
WDSMBeanDumpPlugin are examples that vary in complexity.
Packaged Samples
PTC provides packaged plugin sample code at <Windchill>/utilities/
SystemConfigurationCollector/plugins/examples. This
directory contains packaged samples that maintain the com.ptc.customersupport.*
packaging in a sample subdirectory. These can be examined to see how one can
make use of SQL, QML, Java commands, etc inside a plugin.
Related Websites
• Java Jar Service Provider Specification :
http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/technotes/
guides/jpda/jpda_spis.html
http://java.sun.com/developer/technicalArticles/javase/extensible/
http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/technotes
/guides/jar/jar.html#Service%20Provider
• Java Jar File Specification :
http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/technotes
/guides/jar/jar.html
• Java MBean Object Names :
http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/
best-practices.jsp#mozTocId509360
• Java Compiling :
http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/tooldocs/
solaris/javac.html
• Java Jar Command :
http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/deployment/
jar/build.html
Note
See the descriptions for the tools.properties and
user.properties files in Property Files.
3. Generate the class info objects. Update the serialized info object by entering
the following command from a Windchill shell:
ant -f bin\tools.xml custom_column -Dgen.input=wt.doc
This updates introspection information for descendant classes that are
concrete, for example wt.federation.ProxyDocumentMaster in the
case of wt.doc.WTDocumentMaster.
4. Verify the customization. Obtain an info report for the class and inspect the
UPPER_LIMIT value as described in the preceding steps. The value should
reflect the customization. If the info report value is unchanged, verify that the
generate step actually updated the following serialized info file:
<Windchill>\codebase\wt\doc\
WTDocumentMaster.ClassInfo.ser
5. Adjust the length of the customized column by taking the following steps:
a. Execute the Windchill Upgrade Manager to run the Compare Schema step
only.
Start the Windchill Upgrade Manager within a Windchill shell as follows:
UpgradeManager -cs
For further information about the Windchill Upgrade Manager command
options and upgrading data base schema see the following topics in the
Windchill Help Center:
• Additional Upgrade Manager Commands
• Upgrade Database Schema
Caution
Review the output carefully to ensure the results are what you expect.
You should never execute any SQL that you do not understand, or that
does not seem related to your intended customizations
Customers that do not have Windchill InfoModeler may create services for
listening to events generated by other services (customers that have Windchill
should create listeners by following the instructions in the Creating a Listener
Service section of this Guide).
Here are the steps necessary to create a non-modeled service for listening:
1. Create a service interface
2. Create a standard service class to implement your service interface and extend
the StandardManager class.
3. Compile your interface and class into your Windchill codebase.
4. Register your new service in the codebase with xconfmanager.
Below is an example to create a service that listens for pre- and post-checkin
events. When it "hears" one of these events, it prints a simple message to standard
output. The example assumes the service is in a package called com.acme.listen,
and that the service is called the "Listen" service. If you copy this example, be
sure to change these names to something more appropriate. The example assumes
that you are familiar with the information in the Developing Server Logic on page
2291. This section explains how to write code to register listeners for particular
events.
2292
Change Abstractions ............................................................................................. 2337
Change Items Classes........................................................................................... 2343
Enterprise Abstractions.......................................................................................... 2350
Document Abstractions.......................................................................................... 2357
Part Abstractions................................................................................................... 2360
Change Abstractions ............................................................................................. 2367
Persistence Datastore Sequence Customization...................................................... 2370
QuerySpec ........................................................................................................... 2375
SearchCondition ................................................................................................... 2383
How to Write an IX Application................................................................................ 2391
How to Write Exp/Imp Handlers .............................................................................. 2407
Navigating Through an Object’s Structure with ObjectSet Application ........................ 2420
Product Design eXchange (PDX) Support for Export ................................................ 2442
Adding Export Functionality in the Project Plan Table ............................................... 2449
General Externalization Guidelines ......................................................................... 2454
Hand-coded Externalization Guidelines................................................................... 2455
Migration Guidelines for Classes with Hand-coded Externalization ............................ 2456
Examples of Generated Externalization Code for Evolvable Classes ......................... 2457
Modeling Large Objects ......................................................................................... 2463
Adding and Updating Data Formats for Content Holders........................................... 2469
Content Virus Scanner........................................................................................... 2473
Java Interface Details ............................................................................................ 2474
Configuration and Deployment ............................................................................... 2475
Implementation Guidelines..................................................................................... 2475
The development of the standard, reusable Windchill services caused the need for
a general mechanism to manage the behavior of and interaction between these
services. This service management mechanism specifies a protocol for startup,
shutdown, and communication between Windchill services.
2294
A reference implementation of wt.services.Manager, named wt.services.
StandardManager, provides most of the base functionality required for service
management. If a new type of service does not require any special startup or
shutdown processing, it can extend the base class wt.services.StandardManager
without overriding any of its methods.
Two methods in class wt.services.StandardManager are intended to be overridden
to specialize startup and shutdown processing. These methods are
performStartupProcess and performShutdownProcess. Examples of startup
processing include subscribing to service events and establishing queues for use in
background processing.
Service Management
ManagerService is a manager which is used to startup and provide access to a pre-
defined list of managers. This list includes different managers for services. In
addition to managing managers, the ManagerService provides a synchronous
event dispatch service. This service can dispatch a vetoable or non-vetoable event
to all listeners for the event key. Each listener may or may not object to the event.
The service performs a synchronous "in thread/transaction" notification of each
event listener for the event branch identified by the event key. It calls the
notifyEvent operation on each subscriber.
2296
Change Abstractions ............................................................................................. 2337
Change Items Classes........................................................................................... 2343
Enterprise Abstractions.......................................................................................... 2350
Document Abstractions.......................................................................................... 2357
Part Abstractions................................................................................................... 2360
Change Abstractions ............................................................................................. 2367
Persistence Datastore Sequence Customization...................................................... 2370
QuerySpec ........................................................................................................... 2375
SearchCondition ................................................................................................... 2383
How to Write an IX Application................................................................................ 2391
How to Write Exp/Imp Handlers .............................................................................. 2407
Navigating Through an Object’s Structure with ObjectSet Application ........................ 2420
Product Design eXchange (PDX) Support for Export ................................................ 2442
Adding Export Functionality in the Project Plan Table ............................................... 2449
General Externalization Guidelines ......................................................................... 2454
Hand-coded Externalization Guidelines................................................................... 2455
Migration Guidelines for Classes with Hand-coded Externalization ............................ 2456
Examples of Generated Externalization Code for Evolvable Classes ......................... 2457
Modeling Large Objects ......................................................................................... 2463
Adding and Updating Data Formats for Content Holders........................................... 2469
Content Virus Scanner........................................................................................... 2473
Java Interface Details ............................................................................................ 2474
Configuration and Deployment ............................................................................... 2475
Implementation Guidelines..................................................................................... 2475
Note
A more implicit means of registering events is by not doing so in the
registerEvents method, but by allowing the event to be registered when it is
first emitted. Once this occurs, all listeners subscribing to this event will be
notified.
2298
Service Event Subscription
In order for services to be notified of events occurring within the system, they
must subscribe to each particular service event of interest. To do this, you must
invoke the wt.services.ManagerService.addEventListener method with a listener
and key identifying the event of interest.
The listener specified during subscription must implement the wt.events.
KeyedEventListener interface. It defines the notifyEvent and notifyVetoableEvent
methods. The wt.services.ServiceEventListenerAdapter class is provided as a
utility whereby a listener can extend it and override only the methods that are
required for notification. The notifyEvent is a general method that can be used in
all subscription cases. The notifyVetoableEvent method is more specialized; its
intended use is to provide a means of vetoing an event via an exception.
Typically event listeners are implemented using either anonymous or named
instances of inner classes. This allows the outer class to be designed without
implementing the wt.events.KeyedEventListener interface. This keeps the outer
2300
response to a notification call are included in the transaction of the event emitter.
The following is an example that shows the dispatching of an event like
PersistenceManagerEvent.PREPARE_FOR_MODIFICATION:
2302
Implementing Business Data
3
Types
A business data type can be characterized as an entity object (that is, a knower)
that deals basically with abstracting some crisp and clearly definable piece of
information in the problem domain. Therefore, business data types are primarily
defined by data, not behavior, as in control objects (that is, doers). Because most
of the specification of a business data type is by its attributes, implementation of
this business information typically focuses on the classes’ attributes.
In addition, because business data types are entity objects and are typically
lightweight compared to control objects, they efficiently transport information
between an application and the server in the three-tier (client, server, and
database) architecture.
2304
These initialize methods are empty at the first code generation and must be hand-
implemented because the code generator currently cannot make any assumptions
on what attributes should or should not be initialized. By default, once these
methods are implemented, their code is preserved for subsequent use. To mimic
Java constructor chaining, each initialize method should always invoke its parent
initialize method before doing anything else.
Note that the body of the methods are flagged as "preserve=no." This instructs the
code generator to overwrite the code within a method. Getters and setters can be
preserved by setting this flag to "yes", but in general this is not recommended. On
the other hand, the code generator can be instructed to not generate a getter and
setter for an attribute with the "GenerateAccessors" property on the Windchill tab
set to "False."
The other more general level of validating one or more attributes is to override
and implement the "checkAttributes" method inherited from wt.fc.WTObject. This
method is invoked before the object is stored in the database initially and every
time it is modified. In this case the exception thrown is wt.fc.
InvalidAttributeException, not wt.util.WTPropertyVetoException.
2306
Implementing the checkAttribute Method
The checkAttributes method shown in the following example is an alternative to
the setStatus method shown in the example in Overriding Accessor Methods
earlier in this section. It ensures that closure comments are provided if the status is
to be set to 2.
The checkAttributes method is called by the PersistenceManager to ensure the
state of the object is correct before storing it in the database. The following is an
example of implementing the checkAttribute method:
2308
user to the Administrator. It is equally important to reset the session context at the
end of a service’s startup processing. To guarantee that a session context is always
reset, it should be done in a "finally" clause.
2310
Access control establishes who can act upon what and in what manner. The
enforcement of access control in a business service is explicitly implemented. In
the locking service, for example, when an object is requested to be locked, the
service guarantees that the principal attempting to place the lock has modify
access to the object such that the lock for it can be persisted in the database as
shown below:
2312
Lightweight Services
4
Modeling Business Objects .................................................................................... 2171
Creating New Tablespaces..................................................................................... 2201
The EnumeratedType Class ................................................................................... 2204
Creating an EnumeratedType Subclass .................................................................. 2206
Editing the Resource Info for an Enumerated Type................................................... 2207
Localizing an Enumerated Type.............................................................................. 2209
Extending an Enumerated Type.............................................................................. 2210
The Enumerated Type Customization Utility ............................................................ 2211
GUI Usage of an Enumerated Type ........................................................................ 2213
External Enumerated Value Lists ............................................................................ 2214
Customizing LDAP Mapped Attributes in a User Information Page ............................ 2223
Customizing LDAP Mapped Attributes in a Group Information Page .......................... 2226
Creating a System Configuration Collector Plugin .................................................... 2230
Customizing Column Lengths................................................................................. 2281
Create a Service Interface...................................................................................... 2285
Create a Standard Service Class ............................................................................ 2285
Compile ................................................................................................................ 2288
Register the New Service....................................................................................... 2288
Restart the Method Server ..................................................................................... 2289
Service Management............................................................................................. 2292
Service Event Management ................................................................................... 2296
Implementing Business Data Types ........................................................................ 2303
Lightweight Services.............................................................................................. 2313
Customizing service.properties............................................................................... 2319
Windchill Multi-object Operations............................................................................ 2323
The Object Reference Design Pattern ..................................................................... 2328
The Business Service Design Pattern ..................................................................... 2330
The Master-iteration Design Pattern........................................................................ 2333
Lightweight services reside in the application layer between the client and the
business service layer. Lightweight services are light because they do not start
automatically and dispatch events. Consequently, lightweight services are not
specified in the wt.properties file with wt.services entries.
Lightweight service methods should be designed to do the following:
• Reduce the number of round trips between the client and the server.
• Provide task-specific and higher-level functionality than business service
methods.
• Ensure client transactional integrity.
Lightweight services can dispatch events but should not listen for them. If a
service is not started automatically, it will not be able to hear events that it is
supposed to listen for until it is started.
Lightweight services are an effective means to ensure client transactional integrity.
Several client-server operations can be grouped into a single, lightweight service
method call that will carry out these operations on the server in a single
transaction.
2314
Lightweight services can be implemented in the following two ways:
• Through a modeled class that extends wt.services.StandardManager
• Through a non-modeled, inner class that implements wt.method.
RemoteAccess
The following subsections describe both implementations.
2316
57 Creating Non-Modeled Services for Listening 2317
2318
Customizing service.properties
5
Modeling Business Objects .................................................................................... 2171
Creating New Tablespaces..................................................................................... 2201
The EnumeratedType Class ................................................................................... 2204
Creating an EnumeratedType Subclass .................................................................. 2206
Editing the Resource Info for an Enumerated Type................................................... 2207
Localizing an Enumerated Type.............................................................................. 2209
Extending an Enumerated Type.............................................................................. 2210
The Enumerated Type Customization Utility ............................................................ 2211
GUI Usage of an Enumerated Type ........................................................................ 2213
External Enumerated Value Lists ............................................................................ 2214
Customizing LDAP Mapped Attributes in a User Information Page ............................ 2223
Customizing LDAP Mapped Attributes in a Group Information Page .......................... 2226
Creating a System Configuration Collector Plugin .................................................... 2230
Customizing Column Lengths................................................................................. 2281
Create a Service Interface...................................................................................... 2285
Create a Standard Service Class ............................................................................ 2285
Compile ................................................................................................................ 2288
Register the New Service....................................................................................... 2288
Restart the Method Server ..................................................................................... 2289
Service Management............................................................................................. 2292
Service Event Management ................................................................................... 2296
Implementing Business Data Types ........................................................................ 2303
Lightweight Services.............................................................................................. 2313
Customizing service.properties............................................................................... 2319
Windchill Multi-object Operations............................................................................ 2323
The Object Reference Design Pattern ..................................................................... 2328
The Business Service Design Pattern ..................................................................... 2330
The Master-iteration Design Pattern........................................................................ 2333
The service delegate mechanism uses Java property files to specify the delegates
that are used for each service for a given set of criteria. The main property file is
named service.properties and is located in /Windchill/codebase/.
Instead of adding new entries to the service.properties file, or overriding existing
entries in it, use a separate file. This file must have entries with the same format as
those in service.properties. To use the new property file, add the file’s full path
(relative to the system classpath) to a comma-separated list of files in the
following property located in wt.properties:
wt.services.applicationcontext.WTServiceProviderFromProperties.
customPropertyFiles
2320
Consider the example of creating a new wt.identity.DisplayIdentification delegate.
The DisplayIdentification service is an interface that defines methods for creating
strings that identify an object for user interface display purposes. In service.
properties, several entries exist for the DisplayIdentification service, as follows:
Note
Indentation in this example indicates a continuation of the preceding line,
necessary for presentation in the manual. The entry for each property in a
property file can be on only one line.
2322
Windchill Multi-object Operations
6
Modeling Business Objects .................................................................................... 2171
Creating New Tablespaces..................................................................................... 2201
The EnumeratedType Class ................................................................................... 2204
Creating an EnumeratedType Subclass .................................................................. 2206
Editing the Resource Info for an Enumerated Type................................................... 2207
Localizing an Enumerated Type.............................................................................. 2209
Extending an Enumerated Type.............................................................................. 2210
The Enumerated Type Customization Utility ............................................................ 2211
GUI Usage of an Enumerated Type ........................................................................ 2213
External Enumerated Value Lists ............................................................................ 2214
Customizing LDAP Mapped Attributes in a User Information Page ............................ 2223
Customizing LDAP Mapped Attributes in a Group Information Page .......................... 2226
Creating a System Configuration Collector Plugin .................................................... 2230
Customizing Column Lengths................................................................................. 2281
Create a Service Interface...................................................................................... 2285
Create a Standard Service Class ............................................................................ 2285
Compile ................................................................................................................ 2288
Register the New Service....................................................................................... 2288
Restart the Method Server ..................................................................................... 2289
Service Management............................................................................................. 2292
Service Event Management ................................................................................... 2296
Implementing Business Data Types ........................................................................ 2303
Lightweight Services.............................................................................................. 2313
Customizing service.properties............................................................................... 2319
Windchill Multi-object Operations............................................................................ 2323
The Object Reference Design Pattern ..................................................................... 2328
The Business Service Design Pattern ..................................................................... 2330
The Master-iteration Design Pattern........................................................................ 2333
2324
• Referential integrity association validation during object delete
Windchill-specific collections utilize the Java Collections framework to provide
sets, lists, and maps optimized for Windchill persistent objects. These collections
seamlessly handle Persistables represented as QueryKeys, WTReferences, and
fully-inflated Persistables. The collections also provide numerous APIs for doing
things such as refreshing and inflating, getting sub-collections based on class, and
testing membership. See the wt.fc.collections package in the Javadoc for more
information.
Multi-object event dispatch and notification allows any event (such as PRE_
STORE) to be dispatched and notified as either single- or multi-object. The event
mechanism automatically handles the case where the dispatcher and notifier (that
is, the listener) are inconsistent by converting the multi-object event into single-
object events and looping over the listener and, vice-versa, by converting the
single-object event into a multi-object event and notifying the multi-object
listener. Multi-object events will have collections-based event targets.
Multi-object delegationmakes it possible to request the delegates for a collection
of objects. The multi-object delegate APIs will then map the appropriate delegates
to sub-collections of the collection that would use them. It is then possible to
execute multi-object APIs on the delegate, passing these sub- collections to the
delegate's multi-object APIs. For example, when requesting the "x.y.Z" delegate
for a collection of parts and documents, the result may be that delegate1 matches
the parts and delegate2 the documents; delegate1's multi-object API can then be
called, passing the parts sub-collection. See the Javadoc entry for wt.services.ac.
DefaultServices for more information.
Multi-object exceptions are thrown by multi-object APIs and listeners. These
exceptions provide extended information about the nature of the problem(s)
associated with some of the objects in the passed-in collection. For example, if a
change identity against ten objects failed because three of the objects were
assigned non-unique identities, the resultant exception will indicate the three
individual failures. This is made possible by the addition of "additionalMessages"
to wt.util.WTException.
Multi-object CRUD persistence manager APIs interact with the database using
batch operations, reducing the total number of database interactions for a CRUD
operation to as little as one (more practically, as little as one per table). A "store"
operation passing a collection of 100 parts can employ a single bulk insert to the
database, rather than 100 individual insert operations. See the wt.fc Javadoc entry
for more information.
Batch ("UPDATE WHERE" and "DELETE FROM") statement capabilities
produce Windchill statements that, in the database, are translated as UPDATE
WHERE and DELETE FROM statements. This makes it possible, for example, to
delete all of the associations for a collection of objects in one database hit without
2326
58
Windchill Design Patterns
The Object Reference Design Pattern ..................................................................... 2328
The Business Service Design Pattern ..................................................................... 2330
The Master-iteration Design Pattern........................................................................ 2333
This section describes design patterns that represent Windchill’s current best
practices regarding development of server logic, most notably the design pattern
on how to develop business services. These patterns have emerged during the
development of the Windchill services and should be used as standards and
guidelines when developing new server logic.
2327
The Object Reference Design Pattern
One of the most basic design patterns is the object reference design pattern.
Cookie
The Cookie abstraction provides a class that is used to specify the information to
be associated with and stored as a part of the typed object. When an object asserts
itself as being a Type, the Cookie and its attributes, including all nested attributes,
are code generated into the object along with applicable accessors. If a Cookie’s
cardinality is 0..1, the Cookie and all its nested attributes can be stored as null if
none of the Cookie’s attributes are required. If any of the simple, or structured,
attributes of the Cookie are constrained to be non-null in the database, the Cookie
is forced to be non-null.
Helper
The Helper abstraction provides a class representing the service’s external
interface from which all visible functionality can be invoked. The helper is
intended to specify only static methods and attributes which any other class can
access without having to create any instances. The static methods are typically
Cookie accessors.
Service
The Service abstraction provides an interface that specifies the main functionality
of the service itself, which may or may not be invoked remotely if the interface is
annotated with the @RemoteInterface. Otherwise, the service’s interface will
be available only locally in the server. This interface must be adhered to and
implemented for the service to function properly. Additionally, a standard
implementation of the service’s methods exists. This standard implementation is a
singleton executing on the server and is the default for all Windchill services.
ServiceEvent
The ServiceEvent abstraction provides a common definition of an event that can
be emitted from the service and cause another service to be notified of the event.
This event specifies one or more kinds of occurrences that are used to generate
keys for listeners. Because these specific kinds of occurrences are extremely
simple in nature, only one event per service that defines all occurrences is
specified.
ServiceFactory
The ServiceFactory is a utility to look up implementations of Windchill service
interfaces. The ServiceFactory is primarily intended for remotely invokable
services, but can also be used for server-side services (such as
PersistenceManagerSvr).
Master-Iteration Pattern
This pattern typically establishes two objects that work in concert with one
another. Without one, the other should not exist and is certainly invalid. At the
root are the basic abstractions:
• Mastered
• Iterated
The Mastered interface provides an abstraction of a plug-and-play component in
conjunction with the Iterated interface. The intent is that, in a business model, an
object would assert that it is a master by inheriting the Mastered interface. With
this assertion, the business object can then be mastered through the version control
service’s API. The business object must assert itself as being a kind of mastered
object in order for its instance to be iterated.
This chapter describes the classes and interfaces available in four packages:
• wt.enterprise
• wt.doc
• wt.part
• wt.change2
The classes provided in these packages were designed and intended for you to
extend as you customize Windchill for your own use.
2335
2336 Customization Guide
Change Abstractions
The change2 package includes the basic service methods and change item classes
necessary to support change management. The change management module
provides the means by which users can identify, plan, and track changes to the
product information managed by the Windchill product data management system.
Note
The change2 package replaces the change package available in releases prior
to Release 4.0.
The following figure shows the five conceptual steps in the change management
process.
Analysis Activity
The following figure shows the model for analysis activities:
Change Order
The following figure shows the model for change orders:
Enterprise Abstractions
The wt.enterprise package provides the basic business objects used in the
Windchill system. Most business classes you construct will be extended from the
enterprise classes or their subclasses.
Doc Package
The document classes are implemented based on the pattern established for
revision controlled objects in the wt.enterprise package. These classes,
WTDocumentMaster and WTDocument, provide concrete classes exhibiting the
management characteristics established in wt.enterprise and add specifics for
documents. The properties of a document are specified on the WTDocument class.
Then, for normalization purposes, the sum of the properties are stored on the
WTDocumentMaster. More specifically, WTDocument implements Format
ContentHolder to give it a primary content item and multiple secondary content
Design Overview
The following figure illustrates the basic concepts encapsulated by the Windchill
part reference implementation.
WTPart Properties
WTParts can use other parts to build assemblies using the WTPartUsageLink as
shown in the following figure.
WTPartConfigSpec
A concept of zones has been added to the WTPartConfigSpec to determine which
ConfigSpec is active at any given time. The WTPartConfigSpec is stored, one per
principal, using the WTPartService’s APIs listed in the following figure.
Note
The change2 package replaces the change package available in releases prior
to Release 4.0.
The following figure shows the five conceptual steps in the change management
process.
2369
Persistence Datastore Sequence
Customization
Objective
You want to create a new datastore sequence for use in Windchill.
Background
Windchill uses datastore schema objects to implement a sequence. In Oracle, this
is implemented directly as a sequence schema object. In SQLServer, this is
implemented as a table and access stored procedure.
Scope/Applicability/Assumptions
• This documentation assumes that you have access to the Windchill datastore
directory, <WindchillHome>/db, and access rights to execute DDL scripts
in the target datastore.
• For the modeled customization procedure, it is assumed that the Windchill
Java Annotations support for sequences has been successfully installed and
configured.
Intended Outcome
The end result of this solution is the creation of a datastore sequence.
Solution
Model a sequence class usingWindchill Java Annotations.
Solution Elements
Element Type Description
<MySequence> Java class The class for representing
a datastore sequence in
Windchill.
Customization Points
Limitations
None.
Sample Code
Packaged Samples
None.
Oracle
The following is a sample script for a partNumber sequence that begins with 1 and
has an interval of 20.
exec WTPK.createSequence('partNumber', 1, 20)
Note
See your installed Windchill Javadoc entries for the wt.query package for
further information, including database-specific support for SQL functions and
keywords.
The following example builds a query against a non-modeled table named dual:
QuerySpec qs = new QuerySpec();
subSelect.appendSelect(new ClassAttribute(
wt.part.WTPartAlternateLink.class, WTAttributeNameIfc.ID_NAME),
Bind Parameters
Bind parameters are a database/JDBC feature to take advantage of database
statement preparsing and optimization. Bind parameters are a mechanism for
replacing constants in a SQL statement with replacement parameters at execution
time. For example, the following WHERE clause expression uses the constant
’Engine’: WTPartMaster.name = ’Engine’
This expression can be replaced with the following in the static SQL:
WTPartMaster.name = ?
and the value ’Engine’ can be bound to the parameter ? at execution time.
Query Limit
A QuerySpec attribute, "queryLimit", can be used to limit the results
returned from a query. As the database results are processed, a count is kept for
each item in the result set. This count includes items filtered out due to Access
Control. If the limit is reached, then a PartialResultException will be
thrown. This exception will contain a QueryResult with the items that have been
processed. This could be used in a situation where a client may choose to display
these results after issuing a message that a query limit was reached.
Compound Query
A compound query is a SQL statement that combines more than one component
query into a single SQL statement via a set operator. Set operators include
UNION, UNION ALL, INTERSECT, and MINUS. A compound query is
composed by specifying a set operator and adding component queries. The
component queries are StatementSpec objects so nesting of compound
queries is also supported.
altSelect.appendSelect(new ClassAttribute(
wt.part.WTPartMaster.class, wt.part.WTPartMaster.NUMBER),
new int[] { altPartIndex }, false);
altSelect.appendWhere(new
SearchCondition(wt.part.WTPartMaster.class,
WTPartMaster.NAME, SearchCondition.EQUAL, "ENGINE"), new int[]
{ partIndex });
Sorting
Queries can be used to sort the result data at the database level. However, in
general, database sorting should only be applied to paging queries and queries that
involve only ColumnExpressions. Other types of queries may be
implemented as several separate SQL statements so the sorting is only applied to
the individual statements and not the complete query. Any
ColumnExpression can be used as a sort column. The OrderBy item is used
to pass the ColumnExpression to the StatementSpec. The OrderBy also
indicates the sort order (ascending or descending) and optionally a Locale. If a
Locale is specified, then any character based attributes are sorted with respect to
that Locale using the database language support. For Oracle, this is the National
Language Support (NLS) (see Oracle documentation for more information). Java
Locale values are mapped to Oracle NLS linguistic sort names via
dbservice.properties entries.
Sorting is supported for standard and compound queries via QuerySpec and
CompoundQuerySpec methods.
QuerySpec.appendOrderBy(OrderBy a_orderBy, int[] a_fromIndicies)
CompoundQuerySpec.appendOrderBy(OrderBy a_orderBy)
The QuerySpec method validates the ColumnExpression contained in the
OrderBy against the QuerySpec’s FROM clause. The CompoundQuerySpec
method does not validate. Note that neither method handles appending the
ColumnExpression to the SELECT clause of the statement. This still must be
done via the appendSelect() method. In both cases, it is recommended that a
column alias be set for each ColumnExpression that is contained in an
OrderBy. Depending on the type of query and the number of subclasses
involved, the actual SQL statements may not be valid if a column alias is not used.
Note that the column alias must not be a SQL reserved word (e.g., "number").
The following example builds a compound query using sorting. The names of
parts and documents are returned sorted by name. Following is the SQL for this
query:
SELECT A0.bname sortName
FROM WTPart A0
UNION
SELECT A0.bname sortName
FROM WTDocument A0
ORDER BY sortName DESC
));
To enable checking advance features statement and to successfully execute the
query on the server side, non-access controlled query() method must be used.
query.setAdvancedQueryEnabled(true);
QueryResult queryResult = PersistenceHelper.manager.query (statement);
Note
The QuerySpec must be executed inside the Remote Method server stub.
For more details of the example, see Access Control Consideration.
This section describes the Import Export (IX) Framework and explains how to
customize and use it for various solutions.
The basic unit of job for the framework is importing or exporting a single object.
The framework understands the transactional nature of import and encapsulates a
session of individual imports into one database transaction.
Prerequisite
In order to create the export jar at a client specific location, the following
prerequisite needs to be satisfied before calling the doExport api of
StandardIXBService:
• The context key ISBStreamer.CLIENT_SAVE_AS_FILE needs to be set
with the complete client side file path:
WTContext.getContext().put(IXBStreamer.CLIENT_SAVE_AS_FILE,CLIENT
JAR);
Exporter Class
The details of the exporter class are as follows:
Definition:
public class Exporter extends ExpImporter{…};
Constructor:
Exporter (ApplicationExportHandler _applicationExportHandler,
WTContainerRef _sourceContainer,
String targetDTD,
File localMappingRuleFile,
File policyRuleFile,
String actionName)
throws WTException {
super ("export", ( localMappingRuleFile==null?null:
storeDocument (IxbElement );
sourceContainer: Reference of container.
• targetDTD: string that specifies what DTD must be used for export process.
The IX framework will find appropriate handlers for objects and Document
Type Definition for objects based on this DTD string. The DTD string for
Windchill Release 10.X is standard20.dtd.
Generally the intent was to be able to export objects in any DTD. As you will
see below the class export handlers are resolved using the DTD identifier. The
string targetDTD is also written to the XML file of exported objects, so
the import process could know what DTD should be used to import objects.
• localMapppingRules: XML file or XSL file that is used to override,
change or exclude certain attributes objects when the export process takes
place.
The XSL rule file tests if the exported object has the name of “part_c”, it will
override the Team Template attribute and version information, and tests if the
exported object has the name of “PART_B”, it will override the Team Template
attribute.
If you don’t want to override anything, just pass “null” for the argument
localMapppingRules.
policyRuleFile: XSL file that is used to override, change or exclude certain
attributes objects when the export process takes place.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version=
"1.0">
<xsl:template match="@* | node()" priority="-9">
</xsl:template>
<xsl:template match="WTPart">
<xsl:choose>
<xsl:when test="name='part_c'">
<newInfo>
<teamIdentity>Default (/System)</teamIdentity>
<folderPath>/Design</folderPath>
<versionInfo>
<versionId>B</versionId>
<iterationId>2</iterationId>
<versionLevel>1</versionLevel>
</versionInfo>
</newInfo>
</xsl:when>
<xsl:when test="number='PART_B'">
<newInfo>
<teamIdentity>Default (/System)</teamIdentity>
<folderPath>/Design</folderPath>
</newInfo>
For example the policy rule file specifies that check out exported WTPart objects
in the database after exporting them. If an exported WTDocument object has the
number of “TESTDOC-1”, check it out after exporting it. With all other exported
WTDocuments, lock them in the database after exporting them.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform
version="2.0">
<xsl:output method="xml" indent="no" encoding="UTF-8"/>
<!--
The syntax of Export Policy is standard XSL syntax. The output of
XSLT using the XSL policy file
must only have at most one element of the form:
<actionInfo>
<action>...</action>
</actionInfo>
-->
<xsl:template match="WTPart">
<actionInfo>
<action>Checkout</action>
</actionInfo>
</xsl:template>
<xsl:template match="WTDocument">
<actionInfo>
<xsl:choose>
<xsl:when test="number='TESTDOC-1">
<action>Checkout</action>
-->
</xsl:stylesheet>
If you don’t want to override anything, just pass “null” for the argument
policyRuleFile.
actionName : Action name
An instance of the Exporter must be created via the factory method
newExporter() of the class IxbHelper. For example:
IxbHelper.newExporter (…..);
Note
A list of available export handlers is created based on XML files in the folder
<Windchill>\registry\ixb\handlers. If you pass a wrong DTD in
the constructor of Exporter (a DTD that is not available in the system), you
will not get the handler, so you cannot export the object. Please refer to How
to Write Exp/Imp Handlers on page 2407 for information how to add entry for
an Export handler to XML files.
If you have more than one object, you have to pass them to the exporter in a
collection.
exporter.doExport(collection)
Note
A sample file with comments is distributed along with installation
information.
Note
This option cannot work without a policy file to specify the new object
identities.
<!--
The syntax of Import Policy is standard XSL syntax. The output of XSLT
using
the XSL policy file must only have at most one element of the form:
<actionInfo>
<action>...</action>
</actionInfo>
The following is a sample of a well-formed xsl. In the cases, where there are
no specific actions to be performed, nothing needs to be done, which is
achieved by the following:
<xsl:template match="@* | node()" priority="-9">
</xsl:template>
-->
<xsl:template match='WTPart'>
<actionInfo>
<action>PickExistingObject</action>
</actionInfo>
</xsl:template>
<xsl:template match='WTDocument'>
<actionInfo>
<xsl:template match='EPMDocument'>
<actionInfo>
<action>PickExistingObject</action>
</actionInfo>
</xsl:template>
</xsl:stylesheet>
Note
• <actionInfo> must always exist.
• Criteria can be any valid attribute of the object in XML file.
• Between <xsl:choose>, there can be many <xsl: when test ....> with different
criteria and different action names.
• Only CreateNewObject and SubstituteObject can have action params, and
there are only four action params <newName>, <newNumber>,
<newVersion>, <newIteration>, all of them must be provided.
• SubstituteObject: Substitute the object in the XML file for an object in
the database that has the name, number, version, and iteration provided in the
ImportPolicy file. If such an object doesn't exist, throw an exception. Format
of tag and params for this case is exactly the same with CreateNewObject,
but the <action> is SubstituteObject.
• Ignore: Do not import the object in the XML file. This action doesn't require
any actor.
Importer class
Definition: public class Importer extends ExpImporter
Constructor:
Importer ( ApplicationImportHandler _applicationImportHandler,
WTContainerRef _targetContainer,
String _dtd,
String _ruleFileName,
String _xslPolicyFileName,
String _containerMappingFileName,
String _actorName,
Boolean _overrideConflicts,
Boolean _validate
Parameters explanation:
• applicationImportHandler: an instance of a class that either
implements the interface ApplicationImportHandler or extends the
abstract class ApplicationImportHandlerTemplate
• applicationImportHandler has a job of extracting from the Jar file
that stores XML, and its class must implement two methods:
getContentAsInputStream (String contentId);
getContentAsApplicationData (String contentId);
The later method may always return null to indicate that the file does not exist
in the Windchill DB.
Note
Please see the ApplicationExportHandlerForJar for an example
of implementation of an application import handler.
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
This XSL file says that whenever the import process meet a WTPart named part_
c, then change its team identity template to Default (/System), change its folder
part to /Design, and change its version to B.2, whenever the import process meet a
WTPart with the number PART_B, then change its team identity template to
Default (/System), change its folder part to /Design
If you don’t want to override anything, just pass “null” for the argument
localMapppingRules.
• _xslPolicyFileName : Policy file name
importer.finalizeImport();
• doImport (doc) : This method doesn’t really import the object, but inserts
the XML document that represents the object in to a list to be imported later.
After all XML documents representing all the imported objects are inserted in
the import list, the real import process starts with the call to
finalizeImport().
• finalizeImport(): The import process is actually performed in this
method. It will call to:
doCheckConflicts() - check conflicts for imported objects.
Note
Handlers for non-versioned objects act like the previous versions.
Note
Handlers for versioned objects act different.
Then, the Import Application can do a clean-up, and send messages to the client.
The import process is finished.
For example:
<classExporter>
<class>wt.part.WTPart</class>
<dtd>standardX20.dtd</dtd>
<targetTag>default</targetTag>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</classExporter>
All handlers with the <dtd> tag “standard.dtd” are handlers for export object in
Windchill Release 10.X.
For example:
<classExporter>
<class>wt.part.WTPart</class>
<dtd>standardX20.dtd</dtd>
<targetTag>default<targetTag>
DTD Files
In the folder <Windchill>\codebase\registry\ixb\dtds\
standardX20.dtd there is a file named coreobjects.dtd that is the DTD
file for all objects that will be exported/imported.
MyClass ob = (MyClass)object;
// export the local id
IxbHndHelper.exportAttribute(
ExpImpForLocalIdAttr.class, ob, fileXML, exporter);
// export other attributes that are specific to
// MyObject; e.g. name, number
IxbHndHelper.exportAttribute(
ExpImpForMyObjectAttr.class, ob, fileXML, exporter);
// export version information
IxbHndHelper.exportAttribute(
ExpImpForVersionAttr.class, ob, fileXML, exporter);
// export content
IxbHndHelper.exportAttribute(
ExpImpForContentAttr.class, ob, fileXML, exporter);
}
catch (Exception e) {
LogHelper.devExc ( e,
"exportAttributes: could not export
object=<"+object+">");
}
}
For example:
<elementImporter>
<tag>WTPart</tag>
<dtd>standardX20.dtd</dtd>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</elementImporter>
All handlers with the <dtd> tag “standardX20.dtd” are handlers for import
object in Windchill Release 10.X.
For example::
<elementImporter>
<tag>WTPart</tag>
<dtd>standardX20.dtd</dtd>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</elementImporter>
Note
An object is imported by the following sequence: createObject(),
importObjectsAttributes(), storeObjects(),
importObjectsAttributesAfterStore().
• createObject(): if the object doesn’t exist in database (is not found
by findAmongExistingObjects), it will be created, and all the Ufid
attribute of the object is imported.
• importObjectsAttributes(): import all attributes of the object
storeObjects(): the method storeObjects() will call to
PersistenceHelper.manager.store().
• importObjectsAttributesAfterStore() imports all attributes
that must be imported after the object is stored.
Note
An object is imported by the following sequence: createObject(),
importObjectAttributes(), storeObjects(),
importObjectAttributesAfterStore().
• createObject()
This method is implemented in the class
ExpImpForVersionedObject. The creation of objects will be
delegated to Actor classes, depends on the actor name in the XML file
(The actor name is writen into the XML file by import application).
Particular object handlers don’t have to worry about createObject()
and Actor.
• importObjectAttributes()
• Import all attributes of the object that can be imported before the object is
stored.
• storeObject()
This method is implemented in the class
ExpImpForVersionedObject. The store of objects will be delegated
to Actor classes, depends on the actor name in the XML file (The actor
name is writen into the XML file by import application). Particular object
handlers don’t have to worry about storeObject() and Actor.
• importObjectAttributesAfterStore()
IxbElement fileXML,
Importer importer):
Retrieves the attribute data from the XML DOM Document and set it to
the imported object. This method must be overridden to suit particular
attribute.
Note
The import multithreading property only applies to import of a received
delivery for importable packages.
Property Description
wt.ixb.import.batchSize Sets the batch size for a thread.
Batch size has lower impact on
received delivery import performance.
The property can be set to determine
the number of objects in each import
batch. By default, this property is set to
10000.
wt.ixb.import.maxThreads Number of threads for import. The job
list will be distributed over the number
of threads you define.
Using multiple threads has the most
significant impact on received delivery
import performance. The threads share
the same database connection, which
can impact performance if the threshold
is reached. The number of objects can
also impact performance; the greater
the number or objects, the greater the
performance improvement when using
multiple threads. In general, one thread
will be sufficient for incremental
package deliveries. An initial package
delivery may benefit from multiple
threads, particularly if the import time
<className>xxxx</className>
<methodName>yyy</methodName>
</loadCondition>
Example:
<loadCondition>
<className>wt.ixb.objectset.ObjectSetHelper</className>
<methodName>isPDMLinkInstalled</methodName>
</loadCondition>
Object Collection
When an object is given to the export process, the ObjectSet application does
the job of navigating through the object's structure and collecting all of its related
objects.
The definition of the navigation is taken from a set of XML files known as
navigation?rule files. Additionally, the ObjectSet application uses Java classes
known as generators and filters to collect a set of objects that will be exported
when simple navigation is not enough and some programming logic needs to be
applied.
Object Navigation
The mechanism is an XML-rule-driven “navigator” of Windchill objects. Given a
seed (top level) object the mechanism uses specified rules to navigate from object
to object. The navigation can be performed through a DB link, a foreign key, or a
specified method. Here is an example of rule definition of WTPart. The seed is a
Folder object.
<Windchill>\codebase\registry\ixb\object_set_handlers\
product_struct.xml
<handler>
wt.ixb.objectset.handlers.navigator.ProductStructureNavigator
</handler>
...
<schema>
...
<rule>
<for>wt.part.WTPart</for>
<go>
<byMethod>
<method>navigateFromWTPartToDescribeByDoc</method>
</byMethod>
</go>
</rule>
<rule>
<for>wt.part.WTPartDescribeLink</for>
<go>
<fromForeignKey>
<targetClass>wt.doc.WTDocument</targetClass>
<getMethodName>getDescribedBy</getMethodName>
</fromForeignKey>
</go>
</rule>
...
</schema>
The example above shows both possible types of navigation: From WTPart it
navigates to wt.part.WTPartDescribeLink by a navigate method and
from there using the method getDescribedBy to get the WTDocument that
the WTPart is described by. Then, non-trivial semantic steps can be made.
After collecting, the objects can be filtered out by a set of defined filters. The filter
definition is stored in the same object set registry. The following is an example of
a date/time filter:
<Windchill>\codebase\registry\ixb\object_set_handlers\
filter_by_time.xml
<setFilter>
Note
You must implement all methods that are specified in the rule files.
Such navigation methods take the object to navigate from as a parameter, and
return Enumeration, which will be added to the export set. For example, if you
specify the following rule:
<byMethod>
<method>navigateFromObject1ToObject2</method>
</byMethod>
This appendix provides help for the GUI developer who will be using the IX
Object Collection mechanism by calling:
ObjectSetHelper.computeObjectSetForGivenGeneratorsAnd
Filters(generatorIds, generatorParams, filterIds,
filterParams);
Note
Warning, if there are no filters, you can pass new String[0] for
filterIds and filterParams (Don’t pass null, an exception is thrown)
Generators list
String id Description Localized name Parameters as
– En (for GUI) String
folderContent Collects all objects Cabinet and Folder <class name: oid>,
in a given Cabinet/ Contents like:
Folder (including wt.folder.
subfolders) Subfolder: 1234 or
wt.folder.Cabinet:
1234
productStructure- Collects all Product Structure <class name: oid>,
Navigator children of a given built with active like:
Part (e.g. Parts, configuration wt.part.
which it uses and specification WTPart:123 4 for
Documents which the top-level
describe it)
Note
Actually <class_name:oid> is object local id
There are other generators available which are installation-specific.
exportParam.setActionName(actorName);
exportParam.setClientFileName(jarFileName);
exportParam.setContainer(container);
exportParam.setDetailedLog(detailedLog);
exportParam.setGuiId(reqGUIid);
exportParam.setPolicyFile(policyFile);
exportParam.setPreviewOnly(isPreview);
exportParam.setRuleFile(ruleF);
exportParam.setValidation(false);
exportParam.setGenerators(generators);
exportParam.setFilters(filters);
exportParam.setLocale(RB.getLocale());
exportParam.setJarInJarFlag(jarInJar);
exportParam.getContextData().setIXApplicationContext(appContext);
try{
String formatType = WTProperties.getAppletProperties().
getProperty("wt.ixb.export.formatType");
if(formatType != null){
exportParam.setFormatType(ExportImportFormatType.
toExportImportFormatType(formatType));
}
}catch(Exception e){
}
ObjectSetHelper.computeObjectSetForGivenGeneratorsAndFilters (
generatorIds,
generatorParams,
filterIds,
filterParams);
Import Application
The current Windchill Import GUI and StandardIXBService are the Import
Application. The current Windchill Import OOTB GUI is Import Application
client that calls import process in StandardIXBService (Import Application
server) via IXBHelper.
ObjectImportParameters importParam = new ObjectImportParameters
();
importParam.setActionName(actorName);
importParam.setContainer(container);
importParam.setDataFile(dataF);
importParam.setDetailedLog(detailedLog);
importParam.setGuiId(reqGUIid);
importParam.setPolicyFile(policyFile);
importParam.setPreviewOnly(isPreview);
importParam.setRuleFile(ruleF);
importParam.setValidation(true);
importParam.setLocale(RB.getLocale());
importParam.setOverrideConflicts(overrideC);
importParam.setContainerMappingFile
(containerMappingFile);
importParam.getContextData().setIXApplicationContext
(appContext);
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
import wt.pom.Transaction;
import wt.content.ApplicationData;
import wt.content.ContentItem;
import wt.content.Streamed;
import wt.ixb.publicforapps.ApplicationExportHandlerTemplate;
import wt.ixb.publicforhandlers.IxbElement;
import wt.ixb.publicforapps.Exporter;
import wt.ixb.publicforapps.IxbHelper;
import wt.ixb.objectset.ObjectSetHelper;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.ixb.clientAccess.IXBJarWriter;
import wt.fc.Persistable;
try
{
storeName = this.computeUniqueFileName(fileName);
Streamed sd = (Streamed)obj.getStreamData().getObject();
InputStream is = sd.retrieveStream();
jw.addEntry(is, storeName);
}
catch (IOException ioe)
{
jw.addEntry(file);
file.delete();
}
catch (IOException ioe){
//create exporter
Exporter exporter = null;
}
exporter.finalizeExport();
if ( !(actionName != null && actionName.equals(wt.ixb.
tuner.Exp
ortActionHelper.NO_ACTION_CMD) )){
trx.commit();
}
trx = null;
}
finally {
if (trx != null) {
if ( !(actionName != null && actionName.equals(wt.ixb.
tuner.
ExportActionHelper.NO_ACTION_CMD) )){
trx.rollback();
}
trx = null;
}
}
try{
return resJar;
}
}
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
import wt.pom.Transaction;
import wt.content.ApplicationData;
import wt.content.ContentItem;
import wt.content.Streamed;
import wt.ixb.publicforapps.ApplicationImportHandlerTemplate;
import wt.ixb.publicforhandlers.IxbElement;
import wt.ixb.publicforhandlers.IxbHndHelper;
import wt.ixb.publicforapps.IxbDocument;
import wt.ixb.publicforapps.Importer;
import wt.ixb.publicforapps.IxbHelper;
import wt.ixb.objectset.ObjectSetHelper;
import wt.ixb.actor.actions.IxbActionsHelper;
import wt.util.WTException;
import wt.util.WTMessage;
import wt.ixb.clientAccess.IXBJarReader;
import wt.fc.Persistable;
import javax.xml.transform.stream.StreamSource;
try{
jr = new IXBJarReader(dataFile);
}
catch(IOException ioe){
throw new WTException (ioe);
}
//prepare rule file
String ruleFileName = (ruleFile!=null)? ruleFile.
getAbsolutePath(): null;
String fn = fns[i];
InputStream stream = null;
try{
stream = jr.getStreamByName (fns[i]);
}
catch (IOException ioe){
throw new WTException (ioe);
}
IxbDocument doc = IxbHelper.newIxbDocument(stream,
validate);
Required Artifacts
• Class files: wt.ixb.pdx.*
• XSL path used for transformation: <Windchill>\codebase\
registry\ixb\pdx
• DTD path: <Windchill>\codebase\registry\ixb\pdx\dtds
Default Behavior
• By default it would be Agile compatible.
• By default:
○ “Agile_07.dtd” and “wcxml12pdx_agile.xsl” would be
respective dtd and xsl corresponding to Agile format.
○ “IPC_2571.dtd” and “wcxml2pdx.xsl” would be respective dtd
and xsl corresponding to PDX format.
createExportPackageForPDX
There are four static public APIs (createExportPackageForPDX) in
ExportPackageForPDX to support this functionality.
• Purpose: Convenience method for the common case when objects are
collected without filtering
• Parameters:
○ name — Name of the export package
○ description — Description of the export package
○ exporter — Name of the user who makes export
○ generIds — Array of String id for object set generatory types, e.g.
{”singleDocument”,”productStructureNavigatorWi
thEPM”}
○ generParams — Array of local id for the corresponding seed objects
• Throws: wt.util.WTException
wt.inf.container.WTContainerRef container,
java.lang.String name,
java.lang.String description,
• Purpose: Convenience method for the common case when objects are
collected within a container without filtering
• Parameters:
○ container — Object reference of container
○ name — Name of the export package
○ description — Description of the export package
○ exporter — Name of the user who makes export
○ generIds — Array of String id for object set generatory types, e.g.
{”singleDocument”,”productStructureNavigatorWi
thEPM”}
○ generParams — Array of local id for the corresponding seed objects
• Throws: wt.util.WTException
doExportToPDX
PDXExportHelper.doExportToPDX(sourceContainer,
(ExportPackageForPDX)exportPackage,
PDXExportHandler.XML_ATTR_ATTACHMENTS_OPTION, dir, "zipName");
Background Information
The generated externalization code reads and writes a data stream according to the
following order, with field values for each class ordered alphabetically:
/* version uid
X-10 = 6676079877272797361L
*/
//##end version.uid
//##end writeExternal%writeExternal.body
}
if ( readSerialVersionUID == 6676079877272797361L )
else
wt.fc.EvolvableHelper.requestRewriteOfEvolvedBlobbedObject();
return success;
//##end readVersion%readVersion.body
Example of a readVersion<EXTERNALIZATION_
VERSION_UID> Method
A method is generated for each line in the version/uid mapping table, but the body
is only generated for the uid that matches the current release version. In this
example, the current release version is Windchill R9.0, so its method body will be
generated. The current release version is stored in release.properties, which is
stored in SystemGeneration.jar. The property cannot be overridden by
configuring it in user.properties.
The preserve=maybe tag has been introduced with this automated evolvability
generation to support the generator making the decision regarding whether to
preserve the method body. As with other methods, a particular method can be
permanently taken over by the developer by changing it to preserve=yes.
With these externalization methods generated to be release specific, support for
class evolution is automated but there are still issues that developers will need to
manage. The first is when an attribute (field) is removed from a release. This case
is easy, since the old externalization methods will no longer compile, since they
reference non-existent fields. The developer will need to modify the code to not
set field, but the old field must still be read off the stream, or it will throw a
runtime exception. For example, if the title field is removed from the class, the
previous readVersion<EXTERNALIZATION_VERSION_UID> methods
will need to change the line that reads the title, as follows.
/*title = (String)*/input.readObject(); // field to assign no
longer exists
The second scenario is when attributes (fields) are added. In this case, there will
be no compile error and the code will deserialize without problem, but the object
could possibly be left in an invalid state. The developer should be aware of this
possibility and ensure that the object will be initialized to a valid state.
private boolean readVersion6676079877272797361L( ObjectInput
input, long
readSerialVersionUID, boolean superDone )
//##begin readVersion6676079877272797361L%
readVersion6676079877272797361L.body
preserve=maybe
a1 = (String)input.readObject();
a3 = (Xyz)input.readObject();
list = (Vector)input.readObject();
theOneMoreReference = (ObjectReference)input.readObject();
timeline = (Timeline)input.readObject();
work = (MyAddress)input.readObject();
return true;
//##end readVersion6676079877272797361L%
readVersion6676079877272797361L.body
theOneMoreReference = (ObjectReference)input.readObject();
timeline = (Timeline)input.readObject();
work = (MyAddress)input.readObject();
}
else if ( !superDone ) {
success = super.readVersion( this, input,
readSerialVersionUID, false, false ); // reformatted stream-
return success;
//##end readOldVersion%readOldVersion.body
DDL Generation
The DDL generated by Windchill defines the BLOB columns to be stored in their
own tablespace. This can be controlled for each attribute by changing the
tablespace property under the Windchill tab while modeling. The tablespace must
be defined before the DDL is executed. The name of the default tablespace to
contain BLOBs can be modified using a property in the user.properties file. See
the properties.html file for details on the specific property.
Note
Both Oracle and SQLServer support this tablespace feature. SQLServer
terminolgy refers to this concept as FileGroups.
Small BLOBs
SMALLBLOBs are encoded into Strings before being stored and are mapped to
VARCHAR2(4000) rather than BLOB. Because of the size limitation of 4,000
characters, this option is inflexible and should be used with caution. Your code
should be prepared to handle the possible exception that is thrown if the size of
the attribute grows beyond what can be encoded into 4,000 characters.
Inline BLOBs
INLINEBLOBs combine the features of SMALLBLOB and BLOB to provide
better performance when data is small, but still allow for large data storage
capability. An attribute that is stored as an INLINEBLOB uses two columns:
• A VARCHAR2(4000) column
• A BLOB column
Each object is examined at runtime and, when the data is small enough, it is stored
in the VARCHAR(4000) column; otherwise, it is stored in the BLOB column.
When the data is stored in the VARCHAR(4000) column, no additional datastore
calls are required to read the BLOB data.
Using an INLINEBLOB introduces a fixed cost in terms of storage (two columns
are used instead of one) and additional processing at runtime. However, when the
majority of data is stored “inline” with the table, this cost is negligible in
comparison to the performance benefits. If most of the data exceeds the 4000-byte
limit, BLOB storage is probably more appropriate. However, if it is known that all
data will never exceed the 4000-byte limit, SMALLBLOB should be used.
/*
*
* Lobber is an example of storing BLOBs. BlobClass has three
BLOBs:
* imablob which is LobLocator, and imasmallblob, and
imanothersmallblob
*
* which are
*
*/
try {
atr = createBlobClassRec(lobIt);
long theLength =
(long)PersistenceServerHelper.manager.updateLob(
(Persistable)atr,
atr.getImablob(),
aIs,
false );
len = lobFile.length();
// save a LOB of known length
System.out.println( "file length "+len );
aIs = new FileInputStream(lobFile);
System.out.println( "bytes available on
this InputStream "+aIs.available());
PersistenceServerHelper.manager.updateLob(
(Persistable)atr,
atr.getImablob(),
aIs,
len,
false );
trx.commit();
trx = null;
aIs.close();
}
catch ( FileNotFoundException fnf )
{ fnf.printStackTrace();}
catch ( IOException ioe )
{ioe.printStackTrace();}
finally {
}
catch (WTException WTe) {
WTe.printStackTrace();
}
}
if ( !lob_dir.isDirectory() )
return null;
s_files = lob_dir.list();
for ( int i=0; i
for ( int i=0; i
Note
Any changes made to existing data formats should be treated as
customizations to your code. Be sure to follow the coding practices introduced
in Managing Customizations
A data format:
• Sets the MIME type when a file is downloaded.
• Supplies the icon that will represent the object in browser displays.
• Informs the user of the file format.
You can use a command-line utility, provided by Windchill, to maintain data
format objects.
After adding a new format for a MIME type using DataFormatUtil, you must
add a new line for that format to the wt\content\FormatNameRB.java file
and then run the ResourceBuild utility to generate resource classes from
FormatNameRB.java file. Enter the new line using the following format:
@RBEntry("Display_value")
public static final String unique_number = "MIME type name";
For example, if the MIME type name is Java Archive and display value
desired is Java Archive File, then new entry is as follows:
@RBEntry("Java Archive File ")
public static final String PRIVATE_CONSTANT_58 = Java Archive";
For details on using the ResourceBuild utility, see the Adding and Updating
Data Formats for Content Holders on page 2469.
Note
If you change the MIME type of a data format object, you must stop and
restart the method server to implement the change.
This chapter explains how to customize virus scanner for Content upload.
Security Consideration
Deploy the antivirus software in a secure environment.
Caution
The customized solution and the deployment must be secured, since the
content is transferred to a third-party antivirus software.
Note
wt.content.ClamAVContentProcessor is a sample implementation
class name. The serviceClass attribute value should be the class name of
your implementation.
Implementation Guidelines
Refer to the following implementation of interface to customize the virus scanner
hook in your File Vault system:
package wt.content;
import java.io.*;
import java.util.*;
import xyz.capybara.clamav.ClamavClient;
import xyz.capybara.clamav.commands.scan.result.ScanResult;
/**
* Sample implementation of IContentProcessor interface for Virus
Scanning of content
*/
public class ClamAVContentProcessor implements IContentProcessor {
public ProcessResult processPreStore(InputStream inputStream, Map
<String, Object> data) throws WTException {
byte[] buffer = new byte[1024];
int len;
ProcessResult processResult = new ProcessResult();
try {
//read content and store in byte array
long length = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = inputStream.read(buffer))> -1)
{
baos.write(buffer, 0, len);
length += len;
}
baos.flush();
//WARNING: After reading data from inputStream, do not close
inputStream.
//construct InputStream to pass it to Anti-Virus Software
byte[] bytes = baos.toByteArray();
InputStream is1 = new ByteArrayInputStream(bytes);
//create client to connect securely to Anti-Virus Software of your
choice
ClamavClient clamavClient = new ClamavClient("127.0.0.1");
//scan the content for virus
String operation = (String)data.get(IContentProcessor.OPERATION_
KEY);
String vaultFileName = (String)data.get(IContentProcessor.FILE_
NAME_KEY);
long fileSize = (Long)data.get(IContentProcessor.FILE_SIZE_KEY);
System.out.println("scanning content for operation = "+operation
+", to be stored in vault as "+vaultFileName);