Professional Documents
Culture Documents
Windchill 9.1
Pro/INTRALINK® 9.1
Arbortext® Content Manager™
Windchill PDMLink®
Windchill ProjectLink™
September 2010
Copyright © 2009 Parametric Technology Corporation and/or Its Subsidiary Companies. All Rights Reserved.
User and training guides and related documentation from Parametric Technology Corporation 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.
UNAUTHORIZED USE OF SOFTWARE OR ITS DOCUMENTATION CAN RESULT IN CIVIL DAMAGES AND CRIMINAL
PROSECUTION. 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.
iii
Property Files........................................................................................................................... 2-10
wt.properties file ................................................................................................................ 2-11
service.properties file ........................................................................................................ 2-12
tools.properties file ............................................................................................................ 2-13
user.properties file............................................................................................................. 2-13
db.properties file................................................................................................................ 2-14
Properties and Property Files .................................................................................................. 2-15
Application Context Service/Resource Properties............................................................. 2-15
Contents v
Verify the Customizations ........................................................................................................ 8-39
Summary.................................................................................................................................. 8-41
Contents vii
Sample Code................................................................................................................... 11-14
Attachments ........................................................................................................................... 11-16
Objective ......................................................................................................................... 11-16
Customization Points....................................................................................................... 11-22
Limitations ....................................................................................................................... 11-23
Sample Code................................................................................................................... 11-24
Property Panel ....................................................................................................................... 11-26
Objective ......................................................................................................................... 11-26
Solution ........................................................................................................................... 11-26
Customization Points....................................................................................................... 11-28
Sample Code................................................................................................................... 11-30
Customizing Access Control For Packages ........................................................................... 11-33
Objective ......................................................................................................................... 11-33
Solution ........................................................................................................................... 11-33
Limitations ....................................................................................................................... 11-34
Sample Code................................................................................................................... 11-35
Additional Resources ...................................................................................................... 11-36
Generating HTML Tags for ProductView Visualization Within a JSP Page ........................... 11-37
Tools Overview ...................................................................................................................... 11-40
Available Attributes Report.............................................................................................. 11-40
Debugging ....................................................................................................................... 11-41
Taglib documentation ...................................................................................................... 11-42
Action Report................................................................................................................... 11-43
Action Model Report........................................................................................................ 11-47
Adding Validation Logic for Actions and Properties ............................................................... 11-51
Objective ......................................................................................................................... 11-51
Applicability ..................................................................................................................... 11-51
Structure.......................................................................................................................... 11-51
Participants...................................................................................................................... 11-51
Collaborations ................................................................................................................. 11-52
Consequences ................................................................................................................ 11-53
Implementation................................................................................................................ 11-53
Sample Code................................................................................................................... 11-60
Contents ix
Additional Resources ...................................................................................................... 14-20
Soft Attributes and SCAs ....................................................................................................... 14-21
Constructing and Rendering a Table Using the JSP Framework .......................................... 14-23
Objective ......................................................................................................................... 14-23
Solution ........................................................................................................................... 14-25
Customization Points....................................................................................................... 14-28
Limitations ....................................................................................................................... 14-61
Sample Code................................................................................................................... 14-62
Other Resources ............................................................................................................. 14-63
Windchill Client Architecture Tree .......................................................................................... 14-64
Objective ......................................................................................................................... 14-64
Solution ........................................................................................................................... 14-66
Customization Points....................................................................................................... 14-72
Sample Code................................................................................................................... 14-90
Adding Custom Modeled Attributes to all Table Views .......................................................... 14-91
Attribute Tables...................................................................................................................... 14-92
Objective ......................................................................................................................... 14-92
Solution ........................................................................................................................... 14-92
Sample Code................................................................................................................... 14-95
Generating the Name Attribute Server................................................................................... 14-97
Objective ......................................................................................................................... 14-97
Solution ........................................................................................................................... 14-97
Customization Points..................................................................................................... 14-100
Limitations ..................................................................................................................... 14-100
Sample Code................................................................................................................. 14-101
Additional Resources .................................................................................................... 14-101
Partial Activation of JSCA .................................................................................................... 14-102
Icon Delegates ..................................................................................................................... 14-103
Objective ....................................................................................................................... 14-103
Solution ......................................................................................................................... 14-103
UI Validation......................................................................................................................... 14-109
Objective ....................................................................................................................... 14-109
Solutions........................................................................................................................ 14-110
Customizing the Find Number Field..................................................................................... 14-152
Contents xi
Solution ........................................................................................................................... 17-14
Sample Code................................................................................................................... 17-16
Configuring a Context Picker ................................................................................................. 17-18
Objective ......................................................................................................................... 17-18
Solution ........................................................................................................................... 17-19
Customization Points....................................................................................................... 17-21
Configuring an Item Picker..................................................................................................... 17-24
Objective ......................................................................................................................... 17-24
Solution ........................................................................................................................... 17-25
Customization Points....................................................................................................... 17-27
Configuring an Organization Picker ....................................................................................... 17-31
Objective ......................................................................................................................... 17-31
Solution ........................................................................................................................... 17-32
Customization Points....................................................................................................... 17-34
Configuring a Type Picker...................................................................................................... 17-37
How to Use Type Picker.................................................................................................. 17-37
Overview ......................................................................................................................... 17-41
Customization Points....................................................................................................... 17-43
Attributes and Parameters supported by Type Picker..................................................... 17-44
Source code location....................................................................................................... 17-47
Configuring a User Picker ...................................................................................................... 17-50
Objective ......................................................................................................................... 17-50
Solution ........................................................................................................................... 17-51
Customization Points....................................................................................................... 17-53
Configuring a Participant Picker............................................................................................. 17-57
Objective ......................................................................................................................... 17-57
Solution ........................................................................................................................... 17-57
Customization Points....................................................................................................... 17-61
Sample Code................................................................................................................... 17-63
Contents xiii
Define the <Table> element for the Requirement type ................................................... 19-54
Define the menus for the Requirements tab.................................................................... 19-56
Define the labels, tool tips and mnemonics for the Requirements tab ............................ 19-59
Define <ActionDefinition> elements referred to in the <MenuItem> elements ................ 19-60
Implement an 'enabled decider' class to control when the tab is enabled....................... 19-62
Configurable Link Tables ....................................................................................................... 19-67
Configurable Links Example............................................................................................ 19-67
Installing the Configurable Links Example ...................................................................... 19-67
Uninstalling the Configurable Links Example .................................................................. 19-68
Customizing Configurable Link Tables............................................................................ 19-69
Defining Access Control Policy Rules for Configurable Links ......................................... 19-73
Contents xv
Customizing Life Cycle Administration .......................................................... 24-1
Customizing the Display of Life Cycle Information................................................................... 24-2
Defining Customized Life Cycle Transitions ............................................................................ 24-3
Setting Up a Customized State-Based Versioning Scheme .................................................... 24-3
Adding The Series To StateBasedVersioning.xml And Loading The File ......................... 24-4
Making The Newly Added Version Schemes Available In The Lifecycle Administrator .... 24-5
Creating A Lifecycle Template Which Uses The New Version Series’.............................. 24-6
Setting Up The Object Initialisation Rules ......................................................................... 24-7
How The Revision Scheme Can Be Used......................................................................... 24-9
Contents xvii
Introduction .............................................................................................................................. 29-2
Overview of the Audit Event Framework.................................................................................. 29-3
ProjectAuditEvent Class.................................................................................................... 29-4
Audit Recorders................................................................................................................. 29-7
Windchill Auditing Framework Configuration..................................................................... 29-7
Capturing New Events ........................................................................................................... 29-10
Capturing default information about a new event............................................................ 29-10
Capturing new event-specific auditing information.......................................................... 29-11
Contents xix
The Object Reference Design Pattern ..................................................................................... 35-2
The Business Service Design Pattern ..................................................................................... 35-3
The Master-iteration Design Pattern ........................................................................................ 35-7
Contents xxi
Table Expression in FROM Clause ................................................................................... 39-4
Expression in WHERE Clause .......................................................................................... 39-4
Bind Parameters................................................................................................................ 39-8
Query Limit ........................................................................................................................ 39-8
SearchCondition ...................................................................................................................... 39-9
Compound Query ............................................................................................................ 39-10
Access Control Consideration ......................................................................................... 39-12
Sorting ............................................................................................................................. 39-13
Join Support .................................................................................................................... 39-14
Contents xxiii
Listing Available Data Formats.......................................................................................... 45-3
Renaming a Data Format .................................................................................................. 45-3
Deleting a Data Format ..................................................................................................... 45-4
Contents xxv
Advantages and Disadvantages........................................................................................ E-14
The File Selection Applet .................................................................................................. E-15
The Upload Applet............................................................................................................. E-22
The Download Applet ........................................................................................................ E-41
Index
Chapter Description
Chapter 9, User Interface Technology Added the Adding Custom Code to all
Overview Windchill Client Architecture Pages
section to this chapter
xxvii
Chapter Description
Related Documentation
The following documentation may be helpful:
• What's New for Windchill Release 9.1
• Windchill Installation and Configuration Guide
• Windchill Upgrade Guide
• Windchill Data Loading Reference and Best Practices Guide
• Windchill System Administrator's Guide
• Windchill Business Administrator’s Guide
• Windchill Performance Tuning Guide
xxxiii
• Windchill User's Guide
• Workgroup Manager Customization Guide
If books are not installed on your system, see your system administrator.
Technical Support
Contact PTC Technical Support via the PTC Web site, phone, fax, or e-mail if you
encounter problems using <product name> or the product documentation.
For complete details, refer to Contacting Technical Support in the PTC Customer
Service Guide. This guide can be found under the Self Help section of the PTC
Web site at:
http://www.ptc.com/support/support.htm
The PTC Web site also provides a search facility for technical documentation of
particular interest. To access this page, use the following URL:
http://www.ptc.com/support/support.htm
You must have a Service Contract Number (SCN) before you can receive
technical support. If you do not have an SCN, contact PTC Maintenance
Department using the instructions found in your PTC Customer Service Guide
under Contacting Your Maintenance Support Representative.
Chapter Page
Customization Overview........................................................................ 1-1
The Windchill Development Environment ............................................ 2-1
Getting Started With Windchill Customization ..................................... 3-1
Modeling Business Objects.................................................................... 4-1
Managing Customizations...................................................................... 5-1
Windchill Utilities.................................................................................. 6-1
Password Encryption.............................................................................. 7-1
Customization Tutorial .......................................................................... 8-1
1
Customization Overview
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.
Topic Page
Configuration Options.........................................................................................1-2
Customizations ....................................................................................................1-5
Windchill Customization Points..........................................................................1-8
1-1
Configuration Options
Properties
Properties are created in text files in 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 the Property Files section of the The Windchill Development Environment
chapter on page 2-10 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 Windchill Administrator’s Guide and
the properties.html file in the codebase directory.
Preferences
Preferences are set through the Windchill user interface and do not require a
server restart. They control application behavior1. 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 the Preferences section of the Generic UI Customizations chapter on page
10-15 for some additional information on preferences.
The table below provides just a few of the available preferences:
Preference Description
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 Customizing Workflow
Administration chapter on page 25-1.
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)
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 more information on Info*Engine see Managing Windchill Info*Engine
Tasks on page 5-13.
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 8 Business Intelligence (BI) within Windchill 9.1 to provide out-of-the-
box integration between Windchill and Cognos 8 BI. It also includes pre-built
reports on change management, project items status, and parts/products.
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 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”.
Topic Page
Directory Structure ..............................................................................................2-2
Artifact Management...........................................................................................2-8
Environment Variables........................................................................................2-9
Property Files ....................................................................................................2-10
Properties and Property Files ............................................................................2-15
2-1
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.
ant
Installation of supported version of Ant.
apacheConf
Contains configuration files for Apache Tomcat and Windchill
bin
Contains various batch scripts, such as ToolsSetup.bat.
cgi-bin
Contains the Windchill common gateway interface wrappers.
Class path
We recommend that you not make any modifications to your CLASSPATH after
installation. In particular, do not add the codebase directory. Doing so can cause
Netscape Navigator to incorrectly assume a security violation. (See the Windchill
Installation Guide for further information.)
Path
Your PATH variable should contain <Windchill> \bin and JDK\bin. <Windchill>
contains batch scripts, such as ToolsSetup.bat, required to use the Information
Modeler. (See the Windchill Installation and Configuration Guide for further
information.)
SQL path
You must create (or add to) your SQLPATH variable and set it to the location
where the SQL scripts that create the necessary tables will be written. When you
are in a SQL*Plus session, SQL*Plus searches these directories for SQL scripts.
By default, this value is c:\ptc\windchill\db\sql.
Note: See the Windchill Installation and Configuration Guide for further
information.
Property Files
Windchill uses standard Java property files to determine runtime configuration
properties.
The codebase directory contains:
• wt.properties
Contains properties used for general Java system configuration and Windchill
system configuration.
• service.properties
Contains properties used by the Windchill service delegate mechanism.
• debug.properties
Contains properties used by Windchill code to control debug info capturing.
(See the wt.util package entry in your installed Windchill Javadoc for more
information)
• user.properties
Contains user overrides used by Rational Rose and the Windchill code
generation tools.
• moduleRegistry.properties
Contains list of registered modules.
• moduleDir.properties
Contains home directory for each registered module.
The db directory contains:
• db.properties
Contains properties used by Windchill’s database connection layer to access
the database.
The System Generation jars (SystemGeneration.jar, WindchillUtil.jar &
CommonCore.jar) contain:
• tools.properties
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 (not applets). It
specifies a URL from which client applications can download server
resources such as property files. Client applets use their own codebase URL
as specified in their APPLET tags. Server applications may use this property
when writing dynamically generated HTML to be returned to a client
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
tools.properties file
The tools.properties file contains properties that are used by the System
Generation tools. The following properties within tools.properties are of interest:
• wt.generation.bin.dir, which specifies where .ClassInfo.ser files (serialized
info objects) will be generated, following the package structure.
• wt.generation.source.dir, which specifies where .mData files are expected to
be found and where .java files will be generated, following the package
structure.
Note: Because the source.dir entry informs the code generator of the location of
mData files and, in Rose, the WT_WORK variable informs the model information
export tools of the location of mData files, they must point to the same location.
user.properties file
The user.properties file contains user overrides that are used by the System
Generation tools.
or
wt.services/rsc/default/<Resource Type>/<Selector>|
null/<Requestor>/<Service Priority Number>=<Resource Name>
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,
FormTaskDelegate, NavBarActionDelegate, and NavBarURLActionDelegate.
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.
To be loaded correctly at runtime, files containing application context service
properties must be listed for one of the following properties in wt.properties:
wt.services.applicationcontext.WTServiceProviderFromPrope
rties.customPropertyFiles
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 the Managing
Customizations chapter on page 5-1 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 the Managing Customizations chapter on
page 5-1.
The remainder of this manual describes how to create applications using the
Windchill product and how to customize existing Windchill applications. You are
assumed to be familiar with the third party components used with Windchill: Java,
Rational Rose, Oracle, and the IDE (integrated development environment) of your
choice. Windchill supports any Java IDE customers choose to use. This manual
does not address how to use these products in general, but how to use them as they
relate to Windchill.
This chapter gives you a brief overview of the Windchill development process and
shows how to create a simple application using Windchill. By following this
example, you will perform the major steps in developing an application and verify
that the development environment (as described in the The Windchill
Development Environment chapter on page 2-1) is set up correctly.
Topic Page
An Overview of the Windchill Development Process ........................................3-2
3-1
An Overview of the Windchill Development Process
The process of developing Windchill applications is iterative and model-driven.
You start with Rational Rose, an object-oriented analysis and design tool. Rose
gives you the capability to create a graphic representation — that is, a model — of
an application, its components, their interfaces, and their relationships. Windchill
provides foundation classes that can be loaded into Rose so you can include in the
applications any of the functionality already developed (for example, version
control and the ability to lock objects). In Rose, you can create your own classes
and extend those provided by Windchill.
When you finish the initial modeling phase, you use the Windchill code
generation tool to create Java code from the Rose model. This generated code is
already optimized to take advantage of Windchill’s architecture. You can then
implement in this code the server business logic and the client task logic. A Java
IDE, such as Jbuilder, NetBeans, or Eclipse, is useful for building the client-side
presentation portions of applications that include HTML and Java applets.
Windchill supports any Java IDE customers chooses to use.
Following testing, you can return to the model, make modifications, and repeat
the process without losing work you have already done. This iterative, model-
driven process allows you to create or customize an application, get portions of it
running as quickly as possible, and continually improve it.
– SQLPATH
The SQLPATH specifies the directory in which sql scripts are generated.
It must match the value specified in the tools properties1 file entry named
wt.generation.sql.dir. By default, this value is (wt.home)\db\sql. For
example,
– db.properties
In the windchill\db\db.properties file, ensure your Oracle user name,
password, and service name are entered in this file.
wt.pom.dbUser =<username >
wt.pom.dbPassword =<password >
3. Start the Windchill servers. Open a new console window.
– Start the server manager and a method server by entering the following
command:
java wt.manager.ServerLauncher
1. See the tools.properties file and user.properties file descriptions in the The Windchill
Development Environment chapter.
Tip:
super.initialize();
System.out.println("Person - initialize executing!");
String s = String.valueOf(today.toLocaleString());
setId(s);
}
3. From the File menu, select Save All and, from the Project menu, select
Rebuild All.
5. Insert the following statement as the first line of the init() method in the
CreatePerson.java file:
6. Compile the whole applet by selecting Execute from the Project menu.
2. Ensure your web server, servlet engine, and method server are running. Refer
to the instructions given earlier in Verify The Development Environment (see
page 3-2) if they are not.
3. Open http://<hostname>/<web-app>/wtcore/jsp/CreatePerson.jsp in Mozilla
or Internet Explorer.
4. Enter the name, title, and age (where age must be a number) and press the
Save button.
5. The method server should start up automatically, if it is not already started.
You should see in the output your message about the Person initialize()
method.
Topic Page
Rational Rose and Windchill...............................................................................4-2
Windchill Modeling Heuristics ...........................................................................4-4
Windchill Foundation Abstractions.....................................................................4-8
4-1
Rational Rose and Windchill
The Windchill development environment uses the Rational Rose design and
analysis tool to model business objects. Rose allows you to create a graphical
representation of an application, its components, their interfaces, and their
relationships. Windchill then uses this model to generate code that is used in
server and client development.
You are assumed to be familiar with Rose or learning to use it. This section does
not describe how to use Rose, but how Windchill interacts with it.
Rose offers several kinds of diagrams (as shown in the following figure) intended
to help you analyze your model.
On the left side are some of the various analysis diagrams available in Rose. From
top to bottom, they are: a use case diagram, a sequence diagram, and a state
transition diagram. The right side shows two class diagrams.
The class diagram is the only type of diagram used by Windchill for code
generation. Although we recommend that you use analysis diagrams, that choice
is up to you. Windchill requires only the class diagrams plus some system
specifications that you set within Rose to generate code.
Address is a structured attribute class associated with the Customer class. The
composite aggregation notation indicates that Address is considered a part of the
Customer class. The Address object depends on the existence of the Customer
object. For example, if the Customer class is deleted, the Address class is also
deleted.
An association class allows you to add attributes, operations, and other features to
associations. Because customers register for products, an attributed association is
modeled between Customer and Product. IncidentReportCustomer and
IncidentReportProduct are also link classes, but they have no attributes. You need
not give them a class box.
If any of these concepts or notations are unfamiliar, you should learn more about
UML and Rose before proceeding. Many of the Windchill concepts are explained
using class diagrams.
As you add subclasses to a parent class, in this case extending class WTObject
with Item and then DomainItem, the attributes and methods of each preceding
class are inherited by the subclasses. This approach works in many circumstances.
But sometimes you need only a small percentage of the functionality that is being
inherited. In that case, either you have much more than you actually need in your
object, or you copy just the code you want and add it to your own object, creating
redundancy and potential maintenance problems.
Using this approach, business models have two major kinds of classes: business
information classes and business manager classes.
Business information classes represent the business information and associations
you want to manage and maintain in a database. These classes extend the
foundation classes provided in Windchill. They may implement one or more
business manager interfaces. These classes go back and forth between the client
and the server with data.
Business manager classes represent the business rules that are applied to the
business information objects. These classes extend the Windchill
StandardManager class. Business managers implement an interface class that
provides a client-side API to the business manager methods. The code for
business manager classes is located in the server.
Business managers are intended to implement small portions of functionality. The
knower/doer separation approach allows you to choose which business managers,
the doers, to implement for your business information, the knowers.
Windchill provides you with a number of managers (described in more detail in
the Developing Server Logic chapter on page 36-1) from which you can choose as
LockService Example
In this example, the knower is MyItem, which extends Item (a foundation class
provided by Windchill). Thus, MyItem inherits all the attributes and behavior of
Item. In addition, MyItem implements the Lockable interface.
The notation <<Interface>> is a stereotype. It is a cue to the code generator to add
an Interface modifier to your generated class. This indicates that you must provide
the code for this method in an implementation class. (In Java, an interface is a
collection of operations and final fields without implementation methods which
form an abstract type. A Java class conforms to an abstract type when it
implements an interface. When a Java class implements a Java interface, the class
or one of its subclasses must provide an implementation method for each
operation in the interface.)
Besides the attributes and methods it inherited from Item, MyItem also has the
functionality defined in the Lockable interface.
The left side of the figure shows how to model the interface for a server-side
service on a client. The doer is StandardLockService and it runs on the server. It
inherits from the Windchill StandardManager, which provides standard, basic
operations for a typical manager, such as starting and shutting down. (When you
write your own managers, they also can inherit from StandardManager.)
StandardLockService is the actual implementation of the lock service
functionality and it implements the LockService remote interface.
Foundation Hierarchy
Binary Links
Persistable Objects
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.
Topic Page
Setting Up a Directory Structure for Managing Customized Files and Text
Tailoring ..............................................................................................................5-2
Best Practices for Customizing Files Supplied by PTC ......................................5-9
Best Practices for Adding New Packages and Files..........................................5-26
Modeled To Soft Type Conversion ...................................................................5-29
5-1
Setting Up a Directory Structure for Managing Customized
Files and Text Tailoring
To customize a Windchill system it is often necessary to modify files released by
PTC. Because these files can subsequently be updated by PTC in a maintenance
release, you should use a strategy for managing your files so that your
customizations are not lost when the maintenance updates are installed.
As a general rule, the Windchill Service Pack installer can overwrite any files that
are in established PTC directories under the installation directory where the
Windchill product is installed, regardless of their modification status. It is your
responsibility to manage your customized files to avoid loss of your changes and,
when updates are applied, to be able to easily identify PTC changes that affect the
files you have modified.
PTC recommends that you manage customized files by creating a directory
structure known as the safe area. The actual directory name is
<Windchill>/wtSafeArea, where <Windchill> is the directory where Windchill
Services is installed. By using the wtSafeArea directory, you can store copies of
the customized versions of PTC files where they will not be overwritten by the
Windchill Service Pack installer, as well as keep versions of the original PTC
files. Additionally, the Windchill Service Pack installer uses this safe area to store
updated files that correspond to your customized files. You can then compare the
original files to those updated by PTC to identify where changes have been made.
Doing the comparison can assist you in incorporating PTC updates into your
customized files. PTC provides a script to assist with managing and installing
customized files into your system runtime locations within the <Windchill>
installation directory.
Additionally, if you make changes to resource bundle information files (RBINFO
files), then you must use the <Windchill>/wtCustom directory structure to store
those changes. The ability to change resource bundles requires that you install the
text tailoring option which is selected through the Custom installation type of
Windchill Services, Windchill PDMLink, Windchill ProjectLink, or
Pro/INTRALINK 9.1.
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.
• listSiteChangesIgnored -- lists the files under the
<Windchill>/wtSafeArea/siteMod directory that are not copied to
corresponding <Windchill> installation directories when you run
Note: The following descriptions assume that you have set up your safe area
directory structure, as described in the Directory Structure Diagram for
Customized Files and Text Tailoring section on page 5-2.
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/abcx.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.
Run the following swmaint.xml script from a windchill shell to complete this
step:
ant -f bin/swmaint.xml installSiteChanges
The script is described in PTC Script for Working with Customized Files on
page 5-5.
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, other target options described in PTC Script for Working with
Customized Files on page 5-5 may be helpful in completing this step and later
steps.
3. Update each file that is in the siteMod directory appropriately.
4. After all files in the siteMod directory have been updated, run the following
swmaint.xml script from a windchill shell to copy the files into place for
testing.
ant -f bin/swmaint.xml installSiteChanges
Running this target also lists all files that are not copied. Normally, there
should be no files listed. Inspect any files listed to determine why they were
not copied. If they were in the wrong directory, put them in the correct
directory and rerun the script.
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 temporary 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.
For text changes that are to be used by any applets, you must additionally execute
the MakeJar command as follows:
ant -f <Windchill>/codebase/MakeJar.xml custUpdate
(see Managing Client JAR Files on page 5-14 for more information). For
example, if you add a life cycle state to StateRB.rbInfo, you must run the above
command to see the new state in an applet such as the Lifecycle Administrator.
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 verify that all customized property files are listed in Cust.bom, you can
compare targetFile entries in site.xconf with the files listed in Cust.bom. Any files
listed in targetFile entries that are not in Cust.bom should be added to Cust.bom.
For example, if the site.xconf file has an entry for the following:
targetFile="codebase/wt/change2/change2.properties"
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.
Head JARs only include manifests declaring the component and other JARs upon
which they depend, as well as a JAR index in cases where the head JAR is the top-
level JAR for an applet. PTC distributions leave customization JARs empty, as
these are for customer additions and overrides (e.g. to resource bundles). DSU
JARs are left empty until a maintenance release provides additional files to target
client(s) and/or newer versions of files already present in the corresponding FCS
JAR. The FCS JAR contains all the original files required by a module at FCS
(first customer shipment). The head JAR may list additional JARs upon which it
is dependent after its own components.
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
intended solely for re-use from other JARs. Each arrow implies a dependency
(and essentially inclusion by reference) in the direction of the arrow. It should
thus be clear that all JARs currently defined depend on wtApplet and
3rdPartyApplet with the notable exception of wtBootInst. Thus all duplicates are
consolidated down the tree except from wtBootInst which is completely
independent. The graph shown supports almost all of the Windchill Foundation
applets and will certainly grow over time.
3rdPartyApplet A head JAR which collects all the commonly required 3rd-party libraries into a single
point of reference. As such it does not include any separate resources and thus has no
customization, DSU, or FCS components. Rather it is purely an ordered list of
references to 3rd-party libraries. This list is similar to that found in 3rdparty.jar but has
had all library references which do not make sense for applets (e.g. JSSE) removed.
wtApplet Common base (non-3rd-party) resources shared amongst most Windchill applets. Like
all other shared logical JARs, this JAR serves to collect all resources which would
otherwise have been duplicated in JARs above it. [Note that the intermediate JARs
wtPolicy, wtQB, and wtWork also serve to consolidate duplicates between themselves
and JARs above them.]
wtBootInst The JAR for the Bootstrap loader installation applet. This is currently the only root
applet JAR which is not based on wtApplet. This JAR does duplicate a few resources
from wtApplet, but this JAR was kept separate as it had so little overlap with wtApplet
and without this dependency could be kept extraordinarily small and lightweight.
wtPolicy The JAR for the Policy Administrator and domain browser/selector applets.
wtQB The JAR for the QueryBuilder and Report Manager applets.
wtWork The JAR for the Workflow, Life Cycle, and Team-related Applets (Workflow
Administrator, Team Administrator, Lifecycle Administrator, Initiate Process, Process
Manager, and Setup Participants).
wtFVault The JAR for the External and Remote File Vault Administrator applets.
wtExp The JAR for the Windchill Explorer applet. Note that this JAR references / depends-on
wtPolicy, wtQB, and wtWork as many of the clients supported by these JARs can be
launched from within Windchill Explorer.
Note: This JAR is obsolete in release 9.0.
wtTypeAdm The JAR for the Attribute Administrator, Type Manager, CSM, and Re-Use Manager
applets.
wtLogin The JAR for the login / reauthentication applet (i.e. that accessed via Login.jsp).
ptcAnnotator, The JARs for the Product Structure Explorer (PSE) applet. There are no customizable
ptcCore or inheritable classes in these JARs.
(not shown)
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
-DdoDeepBuild=true
The MakeJar.xml script contains targets allowing a wide variety of JAR building
and maintenance operations to be performed for one or more JARs or sets thereof.
To obtain more information on these targets, execute the following command:
ant -f MakeJar.xml -projecthelp
Note: To use the utility, you must be using the Apache 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:
<Windchill>/codebase/jarContents/<topJarName>Cust.includes
<topJarName> is the leafname of the top-level JAR used by the applet. For
example, the QueryBuilder top-level JAR in the applet tag is wtQB.jar.
Therefore, paste the resources into the file named:
<Windchill>/codebase/jarContents/wtQBCust.includes
6. From a Windchill shell, run the following script from the codebase directory:
ant -f MakeJar.xml custUpdate
Tip:
• The search results are only as accurate and complete as the testing you do.
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.
Note: If, using the above methods, you discover that there are resources missing
from Windchill client JARs that you have not modified, file a problem report with
technical support. Include the following in the report:
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 components of the logical JAR followed by wtApplet.jar, e.g.
for a logical JAR, foo, the entry would be:
Class-Path: fooCust.jar fooDSU.jar fooFCS.jar wtApplet.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
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 the Rational Rose modeling tool 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/ext directory.
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.customPropertyFiles
After running the above command, the wt.properties file is updated to reference
your service provider file, codebase/ext/sitepart/sitepart.properties.
Restrictions
• The tool can will only be able to preserve the following types of attributes that
have been modeled on the class(es) being converted to modeled soft types.
Any other attribute type cannot be converted and the customer will have to
Note: Semantic keys including the modeled class are not presently rebuilt.
The Tool
The tool is run by executing ModeledToSoftType (.sh or .bat) which can be found
in the bin directory for the Windchill installation.
ModeledToSoftType [-help] [-debug|-trace] [ [-skipdb] [-skipfs]
| -checkonly ] MappingFile.xml
-debug | -trace Will describe in more detail each action being performed.
-trace Will include much more detail such as the SQL statements being
executed.
-skipdb Don't perform any of the work that modifies the database.
-skipfs Don't perform any of the work that modifies the Windchill
installation's files.
The tool will output to STDOUT. It will also append it's output with more details
including timestamps to a timestamped log file named ModeledToSoftType.log
in the $(wt.logs.dir) directory.
In this example, imagine the customer has two modeled classes that they want to
make soft types of WTDocument.
package ext.acme;
package ext.acme;
Under that, you'll see information about column descriptors similar to this:
getName() : checkoutInfo.derivedFrom.key.id
getColumnName() : idA3A2checkoutInfo
getJavaType() : long
getSQLType() : java.sql.Types.BIGINT
getLength() : 0
getTableSpaceName() : null
getTableSize() : SMALL
The text to the right of getName() : is the query name. The actual columnname in
the database is on the line right below. The mapping files for the
ModeledToSoftType tool expect to see the query name, not the column
name.(Note: prior to X-12 M050, the tool used the column name to locate the
column descriptor instead of the query name).
This chapter contains information about the xconfmanager and windchill utilities.
Topic Page
About the xconfmanager Utility..........................................................................6-2
About the windchill Command ...........................................................................6-6
About the windchill shell ....................................................................................6-8
6-1
About the xconfmanager Utility
The xconfmanager is a command-line utility that is used to add, remove, and
modify the properties in the Windchill property files. You should use the
xconfmanager (or the System Configurator) to manipulate properties; you should
not manually edit property files.
There are property files that should not be modified using the xconfmanager. The
following registry files are managed by Windchill Information Modeler and they
also should not be edited manually or using the xconfmanager:
associationRegistry.properties
classRegistry.properties
descendentRegistry.properties
modelRegistry.properties
moduleRegistry.properties
moduleDir.properties
debug.properties
The xconfmanager utility saves your changes in the site.xconf file and provides an
option to generate updated property files using those changes. The site.xconf file
contains changes made to Windchill property files, starting with installation and
continuing with each use of the xconfmanager utility or the System Configurator.
The xconfmanager utility is located in the <Windchill>/bin directory.
This chapter describes only the information and instructions necessary to modify
specific Windchill properties. A full description of the xconfmanager utility and
management of the Windchill property files is documented in the Windchill
System Administrator’s Guide in the Administering Runtime Services chapter.
Anyone with write access to the XCONF files and the property files under the
Windchill installation directory can successfully run the xconfmanager utility.
The xconfmanager is executed from the command line from within a windchill
shell. See the About the windchill Command section on page 6-6 for more
information about the windchill shell.
The syntax of xconfmanager command with only commonly used parameters is as
follows:
xconfmanager {-h} {-r <product_root>} {-s <property_pair>}
{-t <property_file>} {--add <property_pair>}
{--remove <property_pair>} {--reset <property_names>}
{--undefine <property_names>} {-d <property_names>} {-p}
For the purposes of modifying Windchill properties, you will primarily use the -s,
-t, and -p parameters as follows:
• Use the -s (--set) parameter to identify the relevant property and specify the
new property value. See the Formatting Property Value Guidelines section
(below) for information about formatting the <property_pair) value.
• Use the -t (--targetfile) parameter to specify the directory location of the
property file. If the file name or path contains spaces, you must enclose the
Tip: If you are unsure as to whether a 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.
• To display the current settings for a property, execute the following command
from the windchill shell:
xconfmanager -d <property_names>
Tip: Use the fully qualified name of the property file to ensure an accurate
reference. If you are sure that there is only one property file that is known to
xconfmanager containing the property, you can omit the -t parameter. When
setting a value for a new property not in a property file, you must include the
-t parameter to name the property file to which the property is added.
Tip: The previous example command did not include the target file in the -t
parameter since the property is known to be in only wt.properties.
-s wt.inf.container.SiteOrganization.name=ACME^ Corporation
On a UNIX system, you can use doubles quotes or you can escape the space
character with \. For example, use either of 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 interpret 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
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:
Action Description
properties Displays the properties as seen by Windchill for the given re-
<resource> source with substitution and other actions executed. It can be
[,...][?key[&key2]...] limited to a given set of keys.
For example:
windchill properties wt.properties — lists all wt.properties
windchill properties wt.properties?wt.server.codebase —
lists server codebase
windchill properties wt.properties?wt.env.* — lists all the
environment variables use by windchill shell
windchill properties — with no arguments generates the help
report
CLASS Run a Windchill class with optional class arguments. For ex-
[CLASS_ARGS] ample:
windchill wt.load.Developer -UAOps
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.
Topic Page
Encrypted Passwords...........................................................................................7-2
7-1
Encrypted Passwords
Objective
You want to encrypt a password currently stored as plain text in a file.
Background
Prior to release 9.1 MR050, Windchill stored password values in plain-text in files
on a file system and relied on appropriate access permissions to restrict access to
those files. As of the 9.1 MR050 release of Windchill, you have the option to
encrypt these passwords so the plain-text value can no longer displayed when the
file is viewed.
Windchill provides out of the box property values that can be encrypted.
However, you can encrypt additional values for Windchill .xconf file managed
properties, as well as, values that are not managed by .xconf files.
Once a value is encrypted, code must be created to properly decrypt this value
prior to use or failures likely will result when the encrypted value is used by the
system.
If you have created an .xconf property value that is a password or is otherwise
sensitive information, consider encrypting the value. If you have customized code
that extends base Windchill classes or reads Windchill .properties files directly, it
may require updating to ensure proper handling of encrypted values.
For complete details regarding encryption, including the encryption mechanism,
accompanying files, SOX compliance, and more, see the "Encrypting System
Passwords" section of the Windchill System Administrator’s Guide.
Scope/Applicability/Assumptions
• Assume you have code that adds a new .xconf property for Windchill use
whose value contains sensitive information. For information on adding
properties see the About the xconfmanager Utility section on page 6-2.
• Assume you have code that adds a property which is not 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 <wt_home>/site.xconf this value appears as:
value="my_password"/>
Solution
Use the Windchill encryption mechanism to provide a secure means to store
sensitive property value information.
Indeally, properties which require encryption should be managed through the
xconfmanager. Doing so will ensure that password encryption will be handled by
a standard practice. However, there may be design considerations or architecture
issues which prevent the property from being xconf managed. Such
considerations may be that 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 Elements
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 APIs.
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 APIs.
This class contains the primary API used to determine if a property
value is encrypted and decrypt it accordingly.
WTKeyStoreUtilWVS Java Class An interface and API that provides methods to encrypt WVS CAD
and Worker configuration passwords.
This class contains code that can be used as an example on how to
encrypt non-.xconf managed properties.
Solution Context
There are two variations of the problem:
1. You want to encrypt and decrypt .xconf managed property values.
2. You want to encrypt and decrypt non-.xconf manager property values.
Each of these uses the encryption and decryption mechanism for various
properties. The difference is that if a property is a single valued managed .xconf
property the xconf framework can be used to set an encrypted value for that
Note: For additional details see the "Encrypting System Passwords" section
of the Windchill System Administrator’s Guide.
This encrypts the property value. However, for the value to be used properly by
code that relies on the value, the code must be updated to decrypt the value prior
Note: Any code that relies on this value must be updated to properly decrypt it.
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 <wt_home> (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”;
String decrypted =
com.ptc.windchill.keystore.WTKeyStoreUtil.decryptProperty(pr
operty,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.
Note: Any code that relies on this value must be updated to properly decrypt
it.
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
String decrypted =
com.ptc.windchill.keystore.WTKeyStoreUtil.decryptProperty(property,encry
pted_value, PATH);
The string decrypted now contains the decrypted value and can be used
properly elsewhere in the code where it is relied on.
Note: Any code that relies on this value must be updated to properly decrypt it.
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 <wt_home> (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”;
String decrypted =
com.ptc.windchill.keystore.WTKeyStoreUtil.decryptProperty(pr
operty,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.
Customization Points
For each solution element whose usage involves the use of parameters, provide a
second 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):
WTKeyStore.java API: public WTKeyStore (final String product_root)
key None String Yes A String that is the key for a value
to remove from the Java keystore
The value
defaults to
environment
variable
WT_HOME,
then wt_home,
and finally the
canonical path
../../../.
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.
Sample Code
}catch(IOException 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);
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
This will add a new regular expression for matching property name patterns.
Again, care must be taken when creating a regular expression. For more
information, see Procedures - Encrypting/Decrypting Dynamic .xconf Managed
Single-Valued Properties on page 7-6.
Additional Resources
This tutorial is intended for programmers who are not that familiar with
Windchill.
Topic Page
Tutorial Overview ...............................................................................................8-2
Create Administrator and User............................................................................8-4
Create a Library and Document ........................................................................8-12
Create a New Attribute Definition and Add it to the Document Type..............8-17
As the End User, Create a Document with the new Attribute...........................8-22
Create a Document Soft Type ...........................................................................8-25
Create an Instance of the New Document Soft Type ........................................8-27
Model a New Document Subclass.....................................................................8-28
Create an Instance of the New Document Subclass ..........................................8-38
Verify the Customizations.................................................................................8-39
Summary ...........................................................................................................8-41
8-1
Tutorial Overview
This tutorial illustrates a minimal configuration to create an environment in which
you can create administrative objects (users, 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.
Goals
In this tutorial you will:
• set up and navigate a Windchill test system
• define soft and modeled types
• create instances of those types
Performing these tasks will:
• confirm that their development environment is properly configured
• shows that UIs adapt to new type and attribute definitions
Assumptions
• Windchill PDMLink standalone or Integral Windchill PDMLink and
Windchill ProjectLink.
• The system is installed, configured and runs. You know how to start and stop
the system.
• You have the ability to compile Java code into the system codebase.
• You have access to the system database instance and permission to create new
schema.
• You can login as the Windchill System Administrator.
Outline
1. As the System Administrator, create Organization Administrator and End
User.
2. As the end user, create a Library and a document instance.
3. As the Organization Administrator create a soft attribute definition and add it
to the standard document type.
4. As the end user, create a document instance which will include the new
attribute.
– Organization
Note: For any other organization you would not need to select
Administrators. But because this is the default site organization, the
15. Select your organization from the Organizations drop down list on the
second level navigation. If there is a table of displayed organizations, it may
also be there.
16. Select the Administrators tab from second level navigation tabs.
17. Select the Add Users… icon.
19. With the Organization tab still selected, select the Creators sub tab. In the
Current View dropdown select Library Creators.
Verify that your end user is now part of the Library Creators group.
At this point in the process, as the System Administrator, you have created an
Organization Administrator and an End User. The Organization Administrator is
also a Soft Attribute and Soft Type administrator. The End User is also a Library
Creator.
3. As the End User, create a new Library. Select the Library tab and select the
New Library icon.
9. Select Finish. You will not be setting attachments during this process.
11. Select the View Information icon to see details about the document.
3. To open the Type and Attribute Manager, select Organization > Utilities >
Type and Attribute Manager.
5. Specify a name for your new Attribute Organizer, and select OK.
6. Select Save.
7. Select the New Attribute icon.
9. Select OK and your new attribute will be displayed in the attribute hierarchy:
10. Before Saving, change the Display Name of the attribute to “Size A”. Note
that the display name can be localized in resource bundles.
12. With Document selected, select the Edit icon. Then select the Template tab.
Within the Template tab, select Attribute Root to enable the Add
Attributes button.
13. Select Add Attribute and from the dialog find and select the sizeA attribute
you created. In the Template tab, select the value cell for sizeA and enter the
default value of 1.
14. Select Save and then select the Check In icon.
4. If you go back and look at the attributes for the first document you created, it
will now display “Size A”, but with no value. Even though you specified a
default value for sizeA, it only applies to instances created after the attribute
existed on the type.
5. Select the Attribute Definition Manager tab, and create another Integer
attribute type as a peer to sizeA called “sizeB”. Save it.
6. Add attribute sizeB to your new document type with default value “2”.
8. Select the General tab. With the type checked out, select the edit icon and
change the Icon to “wtcore/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.
9. Save and check in your type.
2. Within Rose you will first be presented with a Create New Model dialog.
Cancel that dialog for now.
3. Select File > Edit Path Map… and verify that the path map values are
referencing your Windchill installation.
4. Close the Path Map window.
5. Select File > Open, and navigate to, and open the model file:
…\Windchill\src\wt\WTdesigner.mdl
8. In the browser pane, expand the Logical View. Right click Logical View and
select New > Class Diagram. Name the new diagram "com Packages".
Double click on the "com Packages" icon to open the empty diagram.
10. Right click the "com" package in the browser and select New > Package.
Name the new package "acme".
11. Right click the "acme" package in the browser and select New-> Class
Diagram. Name the new diagram "Documents".
12. Double click the Documents diagram icon to open the new empty diagram.
13. Select the Class icon and click in the diagram window. Name the new class
"WTDocument" (it must be this name, as it refers to an existing Windchill
class that you will inherit from). When prompted to "Delete NewClass from
the Model?" select "Yes".
16. Double-click on the new attribute to open the Class Attribute Specification
window.
17. Set the following values:
– Type = Integer
– Initial Value = 3
21. Now you will generate the Java source file, SQL scripts and other artifacts for
your new document class.
– You will find the generated SQL file (to create the new database table)
here:
..Windchill\db\sql\com\acme\create_AcmeModeledDoc_Table.sql
– You will find the generated ClassInfo.ser file (that contains meta data
about the new class) here:
..\Windchill\codebase\com\acme\AcmeModeledDoc.ClassInfo.ser
24. You can inspect the java and sql files to see what was generated (the
ClassInfo.ser file is a binary instance of the ClassInfo java class, so you
cannot inspect it directly).
25. Now you will compile the java file.
26. Open a Windchill Shell. CD to the directory (<Windchill>/src/com/acme) of
the java source file.
27. Compile the java file.
You'll find the compiled class file in the same directory as the ClassInfo.ser
file.
28. Now you will create the table and associated database artifacts for your new
document class. To do this, from within sqlplus, you will execute two scripts:
..\Windchill\db\sql\com\Make_pkg_com_Table.sql
..\Windchill\db\sql\com\Make_pkg_com_Index.sql
30. At the " SQL " prompt execute the two scripts using full path names similar to
this:
@<Windchill>\db\sql\com\Make_pkg_com_Table.sql
@<Windchill>\db\sql\com\Make_pkg_com_Index.sql
31. Now execute a describe command to see the columns in the new table for
your class. Note that there is a "SIZEC" column for the attribute you added
directly to the class.
describe AcmeModeledDoc
You may also want count the number of rows in the table to confirm that it is
empty:
select count(*) from AcmeModeledDoc
3. Now select "Search" button in the bottom right. Four results will be displayed:
the four documents you created.
Chapter Page
User Interface Technology Overview .................................................... 9-1
Generic UI Customizations.................................................................. 10-1
Customizing HTML Clients Using the Windchill JSP Framework..... 11-1
Adding Actions and Hooking Them Up in the UI ............................... 12-1
Gathering the Data for the UI .............................................................. 13-1
Presenting Information in the UI ......................................................... 14-1
Constructing Wizards........................................................................... 15-1
Information Pages ................................................................................ 16-1
Incorporating Pickers in JSP Clients.................................................... 17-1
JSP Customization Scenarios............................................................... 18-1
Customizing the Product Structure Explorer (PSE)............................. 19-1
Customizing Windchill MPMLink ...................................................... 20-1
Customizing Search Functionality ....................................................... 21-1
9
User Interface Technology
Overview
This chapter explains and give 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).
Topic Page
Windchill Client Architecture Overview ............................................................9-2
Adding Custom Code to all Windchill Client Architecture Pages......................9-8
Javascript Functions Overview ...........................................................................9-9
9-1
Windchill Client Architecture Overview
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.
The framework is largely a jsp-based system and is composed of these items:
• JSP Pages/Fragments
• Java Beans
• Custom Tags/Taglibs
• Java Services
• JavaScript functions and 3rd party javascript libraries
• Reusable Components
The internal code to the jsp will contain the necessary data to describe and
configure the sub-components that are used.
begin.jspf
The first and most important is the begin.jspf. This files exists in
codebase/netmarkets/jsp/util/. This file is included in most view jsp pages. The
purpose of this jspf is to:
• Include a tag for rendering the header, and 1st and 2nd level navigation.
• catch exceptions and handles them if they occur within the page
beginWizard.jspf
When constructing a wizard, there is a special beginWizard.jspf file, located in
netmarkets\jsp\components, that should be used instead of the begin.jspf that will
do essentially the same things as the begin.jspf, however, it will not include the
rendering of the header for the 1st and 2nd level navigation.
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 NmObject Utilities in the Gathering the Data for the UI chapter on page 12-15
for more information.
Java Services
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
Validation Service
Validation of actions, properties, and wizard steps 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, properties, or wizard steps
should be displayed, disabled, or hidden. The service will invoke the appropriate
delegates to gather the requested status for that action, property, or wizard step.
As a customization point, you can write a delegate that is mapped to a specific
action, property, or wizard step, that contains logic to indicate when that element
is valid to show, hide, or disable in the user interface.
The validation framework is tied into the Role Based UI framework. Role based
support is included for most actions in the product, and customized actions can
also take advantage of this capability. Role based capability is supported for soft
attributes created via the type manager, not modeled attributes. That validation
service will actually call the role based service as a first pass of validation. If the
action, property, or wizard step is valid for the user based on role, the service will
then invoke the appropriate delegate.
The Validation Service is also used to validate the data entered by the user in
wizards.
• For more information on the Role Based UI framework see Customizing
Role-Based UI Functions - Attribute Visibility on page 9-8.
• For more information on the Validation Service see Adding Validation Logic
for Actions and Properties on page 10-46.
Reusable Components
There is a broad set of components that are built using the framework that can be
reused in customizing your pages.
The basic steps to render many components (table, tree, property panel, etc.) are:
• Describe the component (describe* tags)
• Acquire the necessary data (get* tags)
• Render the component (render* tags)
This section will gloss over what the details of most of the columns and properties
in the tags mean for now, and focus on the overall flow of the page.
Component Description
This part of the lifecycle is used to define the columns/properties that the
component will display. This happens first since the way the data is retrieved may
depend on the properties that are requested.
During the component description phase the developer uses a “describe” tag
handler that tells the infrastructure about the component they would like do
display. The core describe handler is the describeTable, which might look like the
following.
<jca:describeTable var="tableDescriptor" id="my.table.id"
configurable="true"
type="com.myco.MyType" label="${myLabel}">
<jca:setComponentProperty key="actionModel" value="my action
model"/>
<jca:describeColumn id="name"/>
<jca:describeColumn id="nmActions" />
<jca:describeColumn id="status">
<jca:setComponentProperty key="percent" value="true"/>
</jca:describeColumn>
</jca:describeTable>
Data Acquisition
The second phase gets the model data based on the description from the first
phase. In the data acquisition phase, the developer combines a component
description with some additional information on how to actually go and get the
data that will back the component. The developer does this with one of client
infrastructures “get” tags. The most typical usage of the tag might look like the
following:
<jca:getModel var="tableModel" descriptor="${tableDescriptor}"
serviceName="com.myco.MyService"
methodName="getMyObjects">
<jca:addServiceArgument value="${myArgument}"
type="java.lang.Long"/>
</jca:getModel>
What is it doing?
Developers typically do not interact with the ComponentModel object produced
by the get tags. Instead, the developer provides information on some lower-level
API that the client infrastructure invokes and then transforms into a
ComponentModel. The sample code above, for example, will invoke the
com.myco.MyService.getMyObjects(myArgument) method, take the results, and
turn these into a ComponentModel object.
Rendering
This phase produces HTML and JavaScript based on the model data. Rendering is
usually the simplest phase for the developer to set up. The client infrastructure
provides a few render tags that take the ComponentModel produced by a “get” tag
and turns it into HTML and JavaScript. Like the get tags, these tags uses the EL to
accept scoped variable data from the page:
<jca:renderTable model="${tableModel}"/>
What is it doing?
In this case, the table renderer is taking an input ComponentModel assigned to the
scoped variable "tableModel", and rendering it as a table.
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.
The message will appear at the top of the page before the Windchill header is
displayed.
Customization Points
codebase/netmarkets/jsp/util/begin_custom.jspf
TableUtils – package
Name Purpose
getFormNodes (node) Get all the form nodes within the given
parent node. If parentNode is
unspecified, the entire document is
searched.
TreeHandler
Name Purpose
asyncResponseHandler
Name Purpose
rowHandler
Name Purpose
removeRowsFromParentTable
requestHandler
Name Purpose
doRequest (url, options) Make the ajax request for the table.
Used by the above method to change
the url with the options set.
doRequest (url, options) Make the ajax request for the table.
Used by the above method to change
the url with the options set.
This chapter describes user interface customizations that are independent of any
particular Windchill client technology.
Topic Page
Handling Icons for Business Objects ................................................................10-2
Customizing the Handling of Soft Attributes....................................................10-3
Customizing Role-Based UI Functions - Attribute Visibility ...........................10-5
Customizing Role-Based UI Functions - Action Visibility.............................10-14
Preferences ......................................................................................................10-15
Constructing URLs..........................................................................................10-21
Offline Package Customization.......................................................................10-24
System Banner Alert Message ........................................................................10-29
10-1
Handling Icons for Business Objects
These paths must be fully qualified from the Windchill codebase. The location for
all .gif images at this time is wt/clients/image.
The gif image specified must be 16 by 16 pixels.
Class inheritance determines what glyphs are overlaid on an object:
• Subclasses of wt.doc.Document are displayed based on their primary format
and will also inherit the overlays of RevisionControlled.
wt.clients.util.IconCache is the class that clients use to access icons. An example
of its usage follows:
IconCache icons = new IconCache( someWTContextObj );
Image img = icons.getStandardIcon( someWTObject );
Image img2 = icons.getOpenIcon( someWTObject );
Format of AllClients.xml
The format of elements in AllClients.xml is as follows:
<LogicRepository>
<ElementGroup>
<LogicContext dataType="<object type>"/>
<ObjectAttributes id="ObjectAttributes">
<AttributeEditField
id="IBA|<attribute logical form name>"
showDefaultValue="true|false"
inputFieldType="singleLine|multiLine"/>
...
</ObjectAttributes>
</ElementGroup>
...
</LogicRepository>
Example
An example ElementGroup to configure three soft attributes for the modeled base
type wt.part.WTPart is as follows:
<ElementGroup>
<LogicContext dataType="wt.part.WTPart"/>
<ObjectAttributes id="ObjectAttributes">
<AttributeEditField id="IBA|MyBooleanAttribute" showDefaultValue="false" />
<AttributeEditField id="IBA|MyStringAttribute"
showDefaultValue="false"
inputFieldType="singleLine"/>
<AttributeEditField id="IBA|MyStringAttribute2" inputFieldType="multiLine"/>
</ObjectAttributes>
</ElementGroup>
Objective
You want to customize the set of UI components (actions or other UI elements)
that the administrators of the site, organization or containers can manage using the
role-based visibility feature.
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 Windchill Business Administrator’s Guide 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.
As a customizer, you have the ability to customize the list of UI components
available to administrators. You can:
Solution
Modify the roleaccessprefs.xml file (and associated files as needed).
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• The behavior of user roles in Windchill
• The administration of ad hoc access control policies in Windchill
• The actions framework in the Windchill client architecture
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>/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; other
*actions.xml files are generally in
<Windchill>/codebase/config/actions.
roleAccessResource.rbInfo RBINFO Defines the labels to provide in the Uis for the actions or UI
components.
Located in
<Windchill>/wtCustom/com/ptc/netmarkets/roleAccess/.
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.
Regenerate your bundles. The name of the uic should be the same as the
constant for the entry in the resource bundle.
3. In <Windchill>/codebase/actions.xml, modify the create folder action by:
adding the attribute uicomponent=”PROJECT_CREATE_FOLDERS”
<action name=” folder_create” checkaccess=”true”
uicomponent=”PROJECT_CREATE_FOLDERS”>
Customization Points
uic Element
Each UIC in roleaccessprefs.xml represents a UIComponent or action to be
controlled.
Possible
Parameter Default Value Values Req? Description
defaultAll true true | false N The default visibility value for All
Members.
defaultManager true true | false N The default visibility value for Project
Managers.
Note: The permissions are a union of all
permissions across all roles; if you set
defaultManager to false; you should also
defaultAll to false, otherwise managers
will still have access through the
ALL_MEMBERS role.
defaultGuest true true | false N The default visibility value for people in
the Guest role.
Note: Guests are not technically members
of the Project; they are not unioned with
the ALL_MEMBERS role.
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
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" );
Clearing a Preference
There is a big difference between "clear" and "remove". Assuming there are no
division-level defaults or policies, if you "clear" a user preference by setting the
value to be the empty string "", then the value returned will be ""; but if you
"remove" the user-level preference, then the value returned would be system
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
• Visibility: if the preference will appear in the preference manger UI and
visible at what contexts: SITE, ORGANIZATION, CONTAINER or
USER.
– Preference category: The category the new preference will appear under
in the Preference Manager UI.
– Display name: This is the Name column in the Preference Manager UI –
string in the form <RBINFO>:< RBINFO key>
<csvPreferenceCategory
handler="wt.preference.LoadPreference.createPreferenceCategory"
>
<csvname>CUSTOM_PREFERENCE_CATEGORY</csvname>
<csvparentName></csvparentName>
<csvdisplayName>
com.mycompany.pref.mycompanyPreferenceResource:MyNewPreferenceC
ategory.displayName
</csvdisplayName>
<csvdescription>
com.mycompany.pref.mycompanyPreferenceResource:MyNewPreferenceC
ategory.description
</csvdescription>
</csvPreferenceCategory>
<csvPreferenceDefinition
handler="wt.preference.LoadPreference.createPreferenceDefinitio
n">
<csvname>/com/mycompany/MyNewPreference</csvname>
<csvvisibility>USER</csvvisibility>
<csvcategoryName>CUSTOM_PREFERENCE_CATEGORY</csvcategoryName>
<csvdisplayName>com.mycompany.pref.mycompanyPreferenceResource:
MyNewPreference.displayName</csvdisplayName>
<csvdescription>com.mycompany.pref.mycompanyPreferenceResource:
MyNewPreference.description</csvdescription>
<csvlongDescription>com.mycompany.pref.mycompanyPreferenceResou
rce:MyNewPreference.longDescription</csvlongDescription>
<csvdefaultValue>Default Value</csvdefaultValue>
<csvhandler>com.ptc.windchill.enterprise.preference.handler.Str
ingPreferenceValueHandler:4000</csvhandler>
</csvPreferenceDefinition>
<csvLinkPreferenceClientDefinition
handler="wt.preference.LoadPreference.setClientDefinitionLink">
<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
<csvDeletePreferenceDefinition
handler="wt.preference.LoadPreference.deletePreferenceDefinitio
n">
<csvname>/com/mycompany/MyNewPreference</csvname>
</csvDeletePreferenceDefinition>
</NmLoader>
The URLFactory
The URLFactory is a utility class provided to generate relative HREFs and
support the Windchill Single-Point-Of-Contact (SPOC) environment. The
URLFactory has been designed to take in a web-resource at a particular state in
the Windchill system (from a certain request, host etc.) and generate an
appropriate String HREF or URL object corresponding to that resource.
The URLFactory was introduced in Release 6.0 to replace the functionality
provided by GatewayURL, as GatewayURL has a number of significant
limitations in its implementation.
The URLFactory is an instance-based toolkit which may be used in either Java
code directly, JSP Pages or HTML templates. For Java code directly, there are
two constructors defined as can be seen in the Javadoc. The most commonly
utilized one will be:
URLFactory aURLFactory = new URLFactory( );
This will utilize the current server’s codebase and properties for HREF
construction.
Objective
You want offline packages exported from Windchill to display your company’s
brand identity.
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.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Cascading Style Sheets. This guide assumes a good knowledge of how to
specify and write new CSS styles, without going into the specifics of how to
write correct CSS.
• Knowledge and access to the Brand Identity standards for your company.
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
%WT_HOME%\codebase\com\ptc\netmarkets\wp\
ixb directory of your server.
wpofflinestyles.css CSS Style Sheet Contained within the resources.zip file, this 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.
Customization Points
.pageHeader Dark teal background with Defines the border, background image
Windchill background and color of the header.
image (header.gif) and a
dark green bottom border.
.pageHeaderActions White text links. Defines the style of links and text
(CSS rule in normally in the upper right corner of the
wpofflinestyles.css) page.
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;
background-repeat: no-repeat;
… }
.wncApplLogo {
background-image: url(logoWC.gif);
}
.applLogo {
background-repeat: no-repeat;
height: 55px;
background-position:34px;}
2. Restart Tomcat.
This chapter explains and give 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).
Topic Page
Customizing Generic Aspects of JSP Pages......................................................11-2
Customizing UI Branding .................................................................................11-2
Customizing the UI with Ajax...........................................................................11-4
Checkin/Checkout .............................................................................................11-8
Component Access Control.............................................................................11-11
Attachments.....................................................................................................11-16
Property Panel .................................................................................................11-26
Customizing Access Control For Packages.....................................................11-33
Generating HTML Tags for ProductView Visualization Within a JSP Page .11-37
Tools Overview ...............................................................................................11-40
Adding Validation Logic for Actions and Properties......................................11-51
11-1
Customizing Generic Aspects of JSP Pages
This section contains the following topics:
• Customizing UI Branding (page 11-2)
• Customizing the UI with Ajax (page 11-4)
Customizing UI Branding
This section describes how to make changes to certain generic items that appear
on JSP pages such as logos, site-specific information in headers and footers, and
generic error messages.
Note: In making changes to .rbInfo files and image files, be sure to follow the
coding practices introduced in the Resource Info (.rbInfo) Files section in the
Internationalization and Localization on page 40-8.
Caution: Do not change any <key>.constant entries in the .rbInfo files, change
only <key>.value entries.
Setup:
• It is necessary to have an internationalized Java SDK installed so that the
classes can be compiled.
1. Modify <Windchill>/src/com/ptc/netmarkets/util/utilResource.rbInfo (and/or
any of the other language versions) in a text editor. Change entries 4,5,14,15.
There are a few other candidates in this file if one was to make a total
conversion.
Old
4.value=Powered by <A HREF=http://
www.ptc.com/products/windchill/index.htm>Windchill</a>
<sup>®</sup>
5.value=About Windchill ProjectLink
14.value=Windchill ProjectLink Error
15.value=Windchill ProjectLink Error
New
4.value=<your powered by>
5.value=<your about label>
14.value=<your generic error text>
15.value=<your generic error text>
The colors of JSP clients are derived primarily from the style sheet
<Windchill>/codebase/netmarkets/css/nmstyles.css. See the style sheet for more
information.
Logos
To override the logo, add a custom css file that overrides the logo styles:
/**** Application Logos for the header area */
.applLogo {background-repeat: no-repeat; height: 55px; background-position:34px;}
.wncApplLogo {background-image: url(../../netmarkets/images/logoWC.gif);}
.pjlApplLogo {background-image: url(../../netmarkets/images/logoPJL.gif);}
.pdmlApplLogo {background-image: url(../../netmarkets/images/logoPDML.gif);}
.proIApplLogo {background-image: url(../../netmarkets/images/logoPROI.gif);}
.atcmApplLogo {background-image: url(../../netmarkets/images/logoATCM.gif);}
/****/
Objective
Explain and give examples of how to implement an Ajax UI component. Also
gives detailed explanation of Ajax capabilities and overview to the Ajax
infrastructure
Problem: You would like to make an action to be ajax based to make the action
faster and more usable.
Problem: You would like a portion of the page to dynamically refresh when some
event occurs.
Background
To make the Windchill product faster and more scalable, it is necessary to use
some Ajax based operations to cut down on the refresh times of pages. All actions
should be Ajax based where possible. The only actions that should not be Ajax
based are those that update the majority of the page like most of the rows of a
table.
Ajax actions only update the row of the table, or refresh the whole table, that the
action was invoked on. The rest of the page and table are unchanged when the
action is complete.
Scope/Applicability/Assumptions
Assume you have an action that updates an object and refreshes the parent page
when complete and an action that updates all the rows of a table.
Intended Outcome
The result of applying this pattern is that instead of the page refreshing, the row is
updated in-line and highlighted in yellow in the first case, and the second case the
table fades out and refreshes itself without refreshing the rest of the tables and
navigation on the page.
Solution
Specify some Ajax based configuration and code in the action to allow the Ajax
refresh to work.
<your actions>.xml XML Xml file that contains the action definitions
result.addDynamicRefreshInfo(di);
result.setNextAction(FormResultAction.REFRESH_OPENER);
return result;
}
Many examples exist, search actions.xml for ajax=”row” or the processors for the
addDynamicrefreshInfo.
</script>
Example:
refreshDivTag ('sourceContextDropDown', 'myContextPicker',
'/netmarkets/jsp/folder/sourceFoldersDropDown.jsp');
Examples: codebase\netmarkets\jsp\folder\sourceFoldersDropDown.jsp
Sample Code
Examples of usage in out-of-the-box code.
Packaged samples
Picture of part 1 of the interaction when a popup action dynamically updates the
page. The popup action is completed and calls to refresh the opener window.
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
• Familiarity with the basic concepts of checkin/checkout
Intended Outcome
By following these procedures you should be able to add or modify the checkin
and checkout actions.
• Checkout action (no wizard involved)
• Checkin wizard (in this case with primary content but the primary attachment
component will not appear if your object does not support it).
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.EditObjectFormProcessor"
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 then edit or without a processor that is
extending EditObjectFormProcessor is not supported and may result in unstable
code.
Sample Code
Objective
You want to use a consistent interface to view and manipulate access control
permissions on individual Windchill objects.
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 Manage
Security action and also in the Create Document and Create Part wizards.
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.
The feature may be used in two ways:
• The Manage Security action can be added to the object’s action model.
• The Access Control Component can be included as a step in the object’s
Create wizard.
Intended Outcome
Note: The visibility of the action may be constrained by profiles defined in the
Role Based UI. See the Windchill Business Administrator’s Guide for more
details about profile- and role-based visibility administration.
Solution
Use the Access Control Component to provide an interface to view and
manipulate access control on Ad Hoc controlled objects.
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
<csvcategoryName>SECURITY_PERMISSION_CATEGORY</csvcategoryName>
<csvdisplayName>com.ptc.core.security.securityResource:READ</csvdi
splayName>
<csvdescription>com.ptc.core.security.securityResource:READ</csvde
scription>
<csvlongDescription>com.ptc.core.security.securityResource:READ</c
svlongDescription>
<csvdefaultValue>UPDATE</csvdefaultValue>
<csvhandler>com.ptc.windchill.enterprise.preference.handler.Choice
MultiPreferenceValueHandler:readPermission:HIDE,com.ptc.core.secur
ity.securityResource,HIDE:VIEW,com.ptc.core.security.securityResou
rce,VIEW:UPDATE,com.ptc.core.security.securityResource,UPDATE</csv
handler>
</csvPreferenceDefinition>
<csvLinkPreferenceClientDefinition
handler="wt.preference.LoadPreference.setClientDefinitionLink">
<csvname>security/accessPermissionRead</csvname>
<csvclientName>WINDCHILL</csvclientName>
</csvLinkPreferenceClientDefinition>
The initial state of the permission configuration can be modified by changing the
“csvdefaultValue” for the permission entry. The possible values are “HIDE”,
“READ”, and “UPDATE”.
<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>
<jca:action actionName="fileSelectionAndUploadApplet"
actionType="attachments" />
<script type="text/javascript">
setUserSubmitFunction(submitFileContent);
</script>
<command
class="com.ptc.core.security.forms.UpdatePermissionsFormDelegate"
method="" windowType="wizard_step"/>
</action>
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.
Scope/Applicability/Assumptions
Assumptions:
• The wizard that is using the attachment components implements either the
FormatContentHolder or the ContentHolder interfaces.
• The wizard is using the Windchill Client Architecture wizard framework
• The user is familiar with the actions framework
Intended Outcome
By following these procedures you should be able to add or modify the following
components to your UI.
Solution
Use the Attachments Common Components with customized JSP clients
associated to that object type.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving HTML forms, JSP, and JSP custom tags
• The wizard is using the Windchill Client Architecture wizard framework
• The user is familiar with the actions framework
Procedures
<attachments:fileSelectionAndUploadApplet/>
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/>
<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" />
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>
<action name="redirect_primary_attachment"
type="attachments"/>
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.
Sample 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"
formProcessorController="com.ptc.windchill.enterprise.change2.form
s.controllers.ChangeRequestFormProcessorController">
...
...
</jca:wizard>
<attachments:fileSelectionAndUploadApplet/>
Primary attachments
Wizard JSP
<%@taglib prefix="attachments"
uri="http://www.ptc.com/windchill/taglib/attachments" %>
...
<jca:wizard buttonList="DefaultWizardButtonsWithSubmitPrompt">
...
...
.<attachments:fileSelectionAndUploadApplet/>
...
<attachments:primaryAttachment>
...
Objective
You want to display the attributes of some object as label value pairs. You want
the colons to align and the HTML to be section 508 compliant.
Scope/Applicability/Assumptions
This document assumes you are familiar with the configuring and acquiring the
data for a JCA table.
Solution
Use the property panel component to display label/value pairs (or label/input field
pairs) for an object.
Examples:
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving HTML, JSP, JavaScript and Custom taglibs.
• Overview of JCA tags.
• JCA Table
Solution Elements
Element Type Description
The value for <name of the descriptor> can be any name you wish to assign to
your panel.
The reporting tool that gives details about what properties are available can be
accessed here:
http://<HOSTNAME>/<WEBAPP>/netmarkets/jsp/property/propertyReport.
jsp
The value for <name of the data model> can be any name you wish to assign to
your data.
The value for <name of the descriptor> should be that used in your
describePropertyPanel tag.
The value for <name of the data model> should be that used in your getModel tag.
To see more code examples of using the renderPropertyPanel tag look at:
<WT_HOME>/codebase/netmarkets/jsp/carambola/propertyPanel/examples
.jsp
Customization Points
scope page Can be: 'page', No The name of the scope to export the
'request', 'session' or var attribute to.
'application'
(case-insensitive)
var - Any String value Yes Name of the exported scoped variable
for the property panel descriptor.The
type of the variable is
com.ptc.core.components.descriptor.C
omponentDescriptor.
scope page Can be: "page" , No The name of the scope to export the var
"request", "session" attribute to.
or "application"
(case-insensitive).
mode value inherited String form of No Sets the ComponentMode that will be
from com.ptc.core.ui.res used for validation and for data utilities
describePropert ources.Component to determine what kind of GUI
yPanel tag Mode enum: component to return.
VIEW, CREATE,
EDIT, SEARCH
Sample Code
There are many ways to use the renderPropertyPanel tag and its child tags to
display the ComponentModel that is put into page scope by the getModel tag.
To see more code examples of using the renderPropertyPanel tag and its child tags
look at:
<WT_HOME>/codebase/netmarkets/jsp/carambola/customization/examples
/propertyPanel/examples.jsp
<jca:describePropertyPanel var="attributeDisplayPanelDescriptor"
mode="VIEW">
<jca:describeProperty id="number" label="${base_part_number}" />
<jca:describeProperty id="orgid"/>
<jca:describeProperty id="version" label="${base_part_version}"
/>
<jca:describeProperty id="name" label="${base_part_name}" />
</jca:describePropertyPanel>
<jca:describePropertyPanel var="attributeInputPanelDescriptor"
mode="CREATE" >
<jca:describeProperty id="name" inputRequired="true"
label="${part_config_name}" />
<jca:describeProperty id="description"
label="${part_config_desc}" />
</jca:describePropertyPanel>
<wc:batch>
<jca:getModel var="attributeDisplayPanel"
descriptor="${attributeDisplayPanelDescriptor}"
serviceName="wt.fc.StandardPersistenceManager"
serviceName="com.ptc.core.components.forms.CreateAndEditModelGette
r"
methodName="getItemAttributes">
<jca:addServiceArgument
value="${attributeInputPanelDescriptor}"
type="com.ptc.core.components.descriptor.ComponentDescriptor"/>
<jca:addServiceArgument value="${commandBean}"
type="com.ptc.netmarkets.util.beans.NmCommandBean"/>
<jca:addServiceArgument value="${nmcontext.context}"
type="com.ptc.netmarkets.util.misc.NmContext"/>
</jca:getModel>
</wc:batch>
<jca:renderPropertyPanel>
<jca:addPropertyPanel model="${attributeDisplayPanel}"/>
<jca:addSeparator/>
<jca:addPropertyPanel model="${attributeInputPanel}" />
<w:radioButton propertyLabel="${populate}" name="PopulationType"
value="<%=PartConfigurationCommand.POPULATION_BASIC%>"
label="${basic}" checked="true" required="true" />
<w:radioButton name="PopulationType"
value="<%=PartConfigurationCommand.POPULATION_FULL%>"
label="${full}"/>
</jca:renderPropertyPanel>
Objective
You want to customize the default roles, domain structure, or access control
policy rules associated with Packages across all contexts.
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.
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: <WT_HOME>/loadXMLFiles/
packageSharedTeamTemplate.xml XML The XML file that 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: <WT_HOME>/loadXMLFiles/
Limitations
The packageTemplate.xml file applies to the entire site which means you can not
customize it for specific contexts or specific packages.
Sample Code
Example usage:
// comp.ptc.wvs.common.ui.VisualizationHelper is assumed to be imported.
VisualizationHelper visHelper = newVisualizationHelper();
if (visHelper.isWVSEnabled()) //only execute code if WVS is enabled
{
// Embed the create dialog JavaScript somewhere in returned HTML.
// The below is just an example of calling it. Placement within
// HTML is the responsibility of the implementer.
out.println(visHelper.getCreateDialogWindow());
http://<machine_name>/<app_name>/netmarkets/jsp/carambola/createta
bleview/availableAttributesReport.jsp
Enable jcaDebug
To enable the JCA debug feature add the following to the end of any url, that is
JCA:
&jcaDebug=true
For example:
<servername>/Windchill/servlet/TypeBasedIncludeServlet?Containe
rOid=OR%3Awt.pdmlink.PDMLinkProduct%3A4462&oid=VR%3Awt.part.WTP
art%3A5142&u8=1&jcaDebug=true
Attribute Description
Action Name Displays the action type separated by a period and the
action name. The Action Name is also a hyperlink to
the action details page.
Action Model Name Displays the action model name. The Action Model
Name is also a hyperlink to the action model details
page.
Attribute Description
Row Object Displays the object passed into the data utility that the
table cell is displaying info about.
Taglib documentation
Several tags and taglibs are delivered as part of the framework. These taglibs
contain a set of handlers for including components and other common
functionality into your pages.
Refer to the taglib javadoc at the following location:
http://www.ptc.com/view?im_dbkey=61784
The search supports multiple search parameters, regular expressions and case-
insensitive matching.
Location
http://<your machine name>/<app-
name>netmarkets/jsp/carambola/tools/actionReport/action.jsp
Search Supports
• Multiple search parameters
• Regular expressions
• Case-insensitive matching
If there is no information for the particular action, the line is shown blank.
Search Examples
Description
remove ==> Matches: "remove", "list_delete", "related_delete_described_part",
etc.
Action Name
• remov.* ==> Matches: "remove", "remove_deliverable", "removeUses", etc.
• r[a-z]* ==> Matches: "reply", "REVISEITEMS", "reassignLC", etc.
Hot Keys
m ==> Matches: "home"
.* ==> Matches: "home", "productStructure", "documentStructure", etc.
Note: Some matches may be deceiving due to include tags in xml files
Known Bugs
• Opposite facing slashes in file paths
– On Details Page
Definition file: Z:\\Windchill\codebase\config/actions/RelContext-
actions.xml
– In Details Table
• In Internet Explorer
– When pressing the back button from the Details Page, you are given:
Location
The Action Model Report is available at the following location:
http://<your machine name>/<app-
name>/netmarkets/jsp/carambola/tools/actionReport/actionModel.jsp
Search Supports
• Multiple search parameters
• Regular expressions
• case-insensitive matching
Search Examples
Returns action models depending on search:
If there is no information for the attribute of a particular action model, the line is
shown blank.
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
Model File
• only files under \codebase\
• search matches files under "\config\actions\" without having to specify it
Order in Table
This shows the order of the actions within an actionmodel xml file.
Known Bugs
In Internet Explorer
When pressing the back button from the Details Page, you are given:
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.
Participants
The readers of this section should have a general understanding of the Java
programming language, and also some familiarity with the Windchill solution
suite.
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-Select Validation
– Attempts to answer the question: “Should the operation that was just
selected in the UI be allowed to proceed?”
– For example, Can we allow the checkout of parts A, B, and C?
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.
This section will concentrate on the authoring of Validator classes and methods.
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/<vali
daitonKey>/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.)
• Install-based checking (should an action or UI component be available given
the set of solutions installed on a given system?)
• Client-based checking (should an action or UI component be available in a
given client, like DTI or PSE?)
Note: In this case, we would probably want to perform limited pre-validation for
performance reasons.
Example 2:
Note: In this case, we would probably want to perform full pre-validation, since
performance is not as much of an issue (only one object, as opposed to several in
the first example), and accuracy is more important.
The argument list and return types for each Pre-Validation method are identical:
public UIValidationResultSet performFullPreValidation (String
validationKey, UIValidationCriteria validationCriteria, Locale
locale)
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;
import wt.fc.collections.WTCollection;
import wt.folder.CabinetBased;
import wt.folder.CabinetMember;
import wt.folder.Foldered;
/**
* 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.
* @param locale The user's Locale. If a <i>null</i> value is passed in, the
session locale will be used.
* @return UIValidationResultSet
**/
public UIValidationResultSet performLimitedPreValidation (String validationKey,
UIValidationCriteria validationCriteria, Locale locale)
throws WTException
{
logger.debug("ENTERING DefaultWIPValidator.performLimitedPreValidation");
logger.trace(" validtionKey -> " + validationKey);
logger.trace(" validationCriteria -> " + validationCriteria.toString());
if (validationKey.equalsIgnoreCase("checkin") ||
validationKey.equalsIgnoreCase("undocheckout")){
result = performCheckinValidation(validationKey, workable, SELECTED,
(WTUser)(validationCriteria.getUser().getPrincipal()));
}
else if (validationKey.equalsIgnoreCase("checkout")){
result = performCheckoutValidation(validationKey, workable, 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 (validationKey.equalsIgnoreCase("checkin") ||
validationKey.equalsIgnoreCase("undocheckout")){
resultSet.addResult(performCheckinValidation(validationKey,
workable, validationType, (WTUser)(validationCriteria.getUser().getPrincipal())));
}
else if (validationKey.equalsIgnoreCase("checkout")){
resultSet.addResult(performCheckoutValidation(validationKey, workable,
validationType));
}
}
resultSet.appendResults(processNonWorkables(targetObjects, validationKey,
validationType));
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,
UIValidationStatus.ENABLED, null);
}
else{
return new UIValidationResult(validationKey, wtRef,
UIValidationStatus.DISABLED, null);
}
}
if (validationType.equals(FULL)){
goodStatus = UIValidationStatus.ENABLED;
badStatus = UIValidationStatus.DISABLED;
}
else{
goodStatus = UIValidationStatus.PERMITTED;
badStatus = UIValidationStatus.DENIED;
}
if (isNewInWorkspace(orig)){
return new UIValidationResult(validationKey, wtRef, badStatus,
null);
}
}
if (WorkInProgressHelper.isCheckedOut(workable, user) ||
(WorkInProgressHelper.isCheckedOut(workable) &&
WTContainerHelper.service.isAdministrator(((WTContained)workable).getContainerRefer
ence(), user))){
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,
UIValidationStatus.DISABLED, null);
}
else{
return new UIValidationResult(validationKey, wtRef,
UIValidationStatus.ENABLED, null);
}
}
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,
AccessPermission.MODIFY)) &&
(!WorkInProgressHelper.isCheckedOut(workable) &&
(VersionControlHelper.isLatestIteration((Iterated)workable))
&&
(!SandboxHelper.isCheckedOutToSandbox(workable)))){
try{
return refFactory.getReference(workable);
}
catch(WTException wte){
return null;
}
}
if (validationType.equals(SELECTED))
status = UIValidationStatus.DENIED;
else
status = UIValidationStatus.HIDDEN;
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.
This chapter describes how to customize actions and add them to the user
interface.
Topic Page
Windchill Client Architecture Action Framework Overview .......................... 12-2
Tab Models..................................................................................................... 12-17
Customizing Role-based Visibility ................................................................ 12-28
Navigation Stickiness ..................................................................................... 12-37
12-1
Windchill Client Architecture Action Framework Overview
Objective
• You want to add a new action that will be exposed in the user interface.
• You want to add a new action model to the system.
• You want to remove an action from an action model.
Background
The action framework for the Windchill client architecture supports the ability to
configure new actions and action models in the system.
Scope/Applicability/Assumptions
This section describes the action framework for the Windchill Client Architecture.
It does not include information on how to control the display of the action.
Intended Outcome
When you are finished reading this, you should understand how the action
framework works, and how to register actions and action models into the action
framework. You should also be familiar with the tools and debug settings that can
help in your development.
Solutions
• Define a new action and add it to an action model.
• Define a new action model to the system.
• Remove an action from an action model.
Prerequisite knowledge
• XML file structures
Solution Elements
actions.xml .xml Default system xml file for defining actions in the
system.
Run time Location:
<Windchill>\codebase\config\actions
actionmodels.xml *.xml Default system xml file for defining action models ins
the system.
Run time Location:
<Windchill>\codebase\config\actions
The action framework provides a way to define actions and action models within
the system. A service, called the StandardNmActionService manages the set of
actions and action models in the system. Actions and action models are defined
via xml files referred to as actions*.xml and actionmodels*.xml. There is one
default actions.xml and actionmodels.xml file that is delivered with the system.
However, each functional area may also have its own xml file as well which is
also managed by the action service. For customization purposes, a custom-
actions.xml and custom-actionmodels.xml is delivered with the product and are
found in codebase/config/actions relative to the Windchill installation directory.
All other out of the box actions.xml and actionmodels.xml files are also located in
<windchill-install-dir>/codebase/config/actions. The default actions.xml and
actionmodels.xml files contain commonly used actions, such as copy, cut, and
commonly used action models such as wizard buttons. Additional actions*.xml
and actionmodels*.xml files contain actions. and action models related to their
functional areas. (e.g. ChangeManagement-actions.xml contains actions related to
change management, PartManagement-actions.xml contains actions related to
part management).
In general, as a developer you would not have to directly make calls to the
StandardNmActionService. These calls are done via the components that support
display of actions and action models, for example tables, trees, information pages.
Objecttype tag
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.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”. We recommend that all your
objecttypes have a prefix specific to your company to prevent collisions with
object types delivered with the product.
The table below describes the valid parameters for a objecttype. Details about
these parameters can also be found in the codebase/config/actions/actions.dtd.
Default Possible
Parameter Value Values Req? Description
name n/a any combination Yes The name used to reference this object-
of alpha-numeric type
characters
class n/a A valid java class Yes Object class for the enclosed actions
resourceBundle n/a Any valid No Class name for the default resource
resource bundle bundle to use for the properties of the
class name actions that are to be localized
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.
The URL attribute of the command subtag of the action tag can be used to specify
the location of the jsp associated with the action. The value should be the path of
the jsp relative to <WT_HOME>/codebase.
If there is no URL parameter specified, then the location of the jsp is assumed to
be <WT_HOME>/codebase/netmarkets/jsp/<objecttype name>/<action
name>.jsp. For example, the jsp of the "create" action (as show above on page
12-4) would be: <WT_HOME>/codebase/netmarkets/jsp/document/create.jsp.
Naming conventions for the name of an action can be any combination of alpha-
numeric characters. We recommend that all your actions have a prefix specific to
your company to prevent collisions with names of actions delivered with the
product.
The table below describes the valid parameters for a action. Details about these
parameters can also be found in the codebase/config/actions/actions.dtd.
Possible
Parameter Default Value values Req? Description
name n/a all Yes This is the name by which the action will
be referenced
required false false / true No Used for an wizard action that represents
a step in the wizard. Specifies the wizard
step is required.
If necessary, place a <command> tag in the body of the <action> tag to define the
processing aspects of the action.
<command
class="com.ptc.windchill.enterprise.doc.forms.CreateDocFormProcess
or" method="execute" windowType="popup"
onClick="validateCreateLocation(event)"/>
The class attribute defines what class to use for processing. The method attribute
defines what method to execute in the class. The windowType attribute
determines what window action to take. In the example above the command is for
the New Document action which is a Wizard so the windowType is “popup”. The
framework will add javascript that launches this action in a new window. The
specified class and method are executed upon submit of the wizard.
Possible
Parameter Default Value Values Req? Description
Possible
Parameter Default Value Values Req? Description
value n/a Any object Yes This action will be disabled for the
types. It can object type/s mentioned in the
be comma "Possible values". Actions will be
separated. disabled in Third Level Navigation,
Row Level action. No filtering will be
done for MenuBar and Table Tool Bar
actions.
Possible
Parameter Default Value Values Req? Description
value n/a Any object Yes This action will be enabled only for the
types. It can objecttype/s mentioned in the "Possible
be comma values". Actions will be enabled in
separated. Third Level Navigation, Row Level
action. No filtering will be done for
MenuBar and Table Tool Bar actions.
objecttype name all Corresponds to the name of the objecttype specified in the
actions.xml file.
action name all Corresponds to the name of the action specified in the actions.xml
file.
purpose title title: localizable text for the title bar if the action is for a wizard
description
description: the localizable text for the label of the action
tooltip
icon tooltip: the localizable text shown on mouse over of the action
morurlinfo icon: image file, relative to codebase/netmarkets/images
hotkey
moreurlinfo: parameters used to size the window for this action
hotkey: the alphanumeric key to trigger this action.
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>
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.WTDocuments.
name n/a all Yes This is the name by which the action
model will be referenced
defaultActionNa First action in the Action name for Specifies which action should be
me model is used by one of the actions highlighted by default. This is only
default in the model. applicable if the model is used as a
third level navigation bar.
name n/a Name of any Yes This is the name of an action defined in
action defined in an actions.xml file
an actions.xml file
type n/a Name of any Yes This is the name of an objectype defined
objectype defined in an actions.xml file.
in an actions.xml
file
Naming conventions for the name of an action model can be any combination of
alpha-numeric characters. Most action models are names include the component
that they are used in. Your action models should have a prefix specific to your
company to prevent collisions with other action models delivered with the
product.
name n/a Name of any action Yes This is the name of an action model
model defined in an defined in an actionmodels.xml file.
actionmodels.xml file An example of where an action model
with submodels is used is for the File
menu on the Folders table.
The entries follow the same format as that of the actions, as noted in Procedure -
Localizing an action on page 12-9.
object.relatedItems.description.value=<U
class='mnemonic'>R</U>elated Objects
Customization Points
As mentioned earlier in Solution Elements section on page 12-2, there are two
files, custom-actions.xml and custom-actionmodels.xml, that are delivered with
the product. If you want to add/modify an action/actionmodel you can put the
changes in these files.
It is important to note that if you have an <objecttype> element in the custom-
actions.xml file, and that type exists within another actions.xml file, the actions
from your file will be added to the full set of actions supported for that type. This
Sample Code
Objective
You want to change something in the header section of the page. Examples: Add
and remove tabs or sub tabs, Change logo, change other styles.
Background
The tabs and sub tabs rendered in the header area are actions in action lists just
like any other actions in the system. The action lists are being displayed by a
special tag that knows how to render them as tabs and sub tabs instead of
rendering them in any of the other formats found throughout the system. Adding
tabs and sub tabs is very much like adding any other action into the system, but
there are some additional special consideration.
The look and feel of the header and footer areas is controlled by CSS classes in
nmstyles.css. A detailed list of the styles used and a description of their purpose is
provided in this document in the Procedure - Changing the header or footer look
and feel section on page 12-22.
Scope/Applicability/Assumptions
• Assume you need to change the look and feel of Windchill to conform to your
company's branding.
• Assume you need to add a new tab or sub tab to the main navigation of the
product.
• Assume you need to remove an existing tab or sub tab from the main
navigation of the product.
Solution
Create new actions, an action model, and JSPs for the tab and sub tabs to be
added.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving CSS, JSP and XML.
• The actions framework in the Windchill client architecture. For more
information see, Windchill Client Architecture Action Framework Overview
on page 12-2.
The management of RBINFO file customizations. For more information see,
Procedure - Localizing an action on page 12-9.
<mytab>/<list>.jsp JSP This is the JSP file you will create as the
default content for the tab you are adding.
You can create as many additional JSPs to
associate with sub tabs as you need.
You can now add subtabs to your new action model. You must create at least one
sub tab whose name and type match the defaults specified in the action model tag.
<csvLinkPreferenceClientDefinition
handler="wt.preference.LoadPreference.setClientDefinitionLink">
<csvname>mytabStickyAction</csvname>
<csvclientName>WINDCHILL</csvclientName>
</csvLinkPreferenceClientDefinition>
<csvPreferenceDefinition
handler="wt.preference.LoadPreference.createPreferenceDefinition">
<csvname>mytabStickyOid</csvname>
<csvvisibility>HIDDEN</csvvisibility>
<csvcategoryName>DISPLAY_CATEGORY</csvcategoryName>
<csvdisplayName>wt.preference.preferenceResource:UNASSIGNED_WIT
H_NAME</csvdisplayName>
<csvdescription>wt.preference.preferenceResource:UNASSIGNED_WIT
H_NAME</csvdescription>
<csvlongDescription>wt.preference.preferenceResource:UNASSIGNED
_WITH_NAME</csvlongDescription>
<csvdefaultValue/>
<csvhandler>com.ptc.windchill.enterprise.preference.handler.Str
ingPreferenceValueHandler:</csvhandler>
</csvPreferenceDefinition>
<csvLinkPreferenceClientDefinition
handler="wt.preference.LoadPreference.setClientDefinitionLink">
<csvname>homeStickyOid</csvname>
<csvclientName>WINDCHILL</csvclientName>
</csvLinkPreferenceClientDefinition>
</NmLoader>
<!-- Your content should occur between begin.jspf and end.jspf -->
<H1>Hello World!</H1>
Customization Points
• Procedure - Changing the application logo
• Procedure - Changing the header or footer look and feel
• Procedure - Removing a Main Tab
• Procedure - Removing a Sub Tab
• Procedure - Context Bar
After removing the change tab from the main navigation action model above. The
list will look like this:
<!-- Main navigation -->
After removing the Change Monitor sub tab from the product sub tab list above.
The list will look like this:
<model name="product navigation">
<action name="list" type="product"/>
<action name="separator" type="separator"/>
<action name="view" type="object"/>
<action name="listFiles" type="product"/>
<action name="listTeam" type="product"/>
<action name="listProduct" type="work"/>
<action name="view_forum" type="project"/>
<action name="MyWorkspace" type="product"/>
<action name="listTemplates" type="product"/>
<action name="listUtilities" type="product"/>
</model>
@Override
protected NmHTMLActionModel getActionModel() throws WTException {
//Insert customized code
}
@Override
protected GUIComponentArray getLeftSideComponents() throws
WTException {
//Insert customized code
}
@Override
protected GUIComponentArray getRightSideComponents() throws
WTException {
//Insert customized code
}
Register MyContextBarDelegate
As an example you can view the components.service.properties.xconf located
under: Windchill\codebase\com\ptc\core\components. Though the properties
should be added to a specific customized service.properties.xconf file.
In the above example you would write something like the following:
<Service context="default"
name="com.ptc.windchill.enterprise.navigation.ContextBarDelegate">
<Option requestor=" wt.inf.library.WTLibrary"
serviceClass="com.ptc.windchill.enterprise.org.navigation.MyContex
tBar" selector="cbNav" />
</Service>
import wt.util.WTException;
import
com.ptc.windchill.enterprise.navigation.WTContainedNavigationDeleg
ate;
/**
* Creates a new instance of MyObjectNavigationDelegate
*/
public void MyObjectNavigationDelegate () {}
/**
* All MyObjects are displayed on mytab, so when this class is
* invoked, The tab from context object should always be mytab.
*/
protected final String getSelectedTabFromContextObject()
throws WTException
{
return "mytab";
}
There are other methods that you may wish to override but
getSelectedTabFromContextObject() is the only one required for this use case.
Register MyObjectNavigationDelegate
For some examples you can view the components.service.properties.xconf located
under: Windchill\codebase\com\ptc\core\components. Though the properties
After registering you will need to run xconfmanager -p from a windchill shell and
restart the method server.
In some cases it may be necessary to increase the order of the delegate. Essentially
this increases the priority of the delegate and bumps it above other delegates.
Currently this is done in the out of the box product for the
VerstionableChangeItemNavigationDelegate like so:
<Service context="default"
name="com.ptc.windchill.enterprise.navigation.NavigationDelegate">
<Option order="1"
requestor="wt.change2.VersionableChangeItem"
serviceClass="com.ptc.windchill.enterprise.change2.navigatio
n.VersionableChangeItemNavigationDelegate"
selector="mainNav" />
</Service>
When order is used be sure to use an order higher than the delegate you are trying
override.
Limitations
In order to get your tab and sub tab to display and highlight correctly you must
follow the following conventions
• You must place your sub tab JSPs in a directory that exactly matches the
name you gave to your main tab in Procedure - Adding a Main Tab on page
12-18. In that example the main tab name is "mytab".
• You must create a JSP whose name exactly matches the defaultActionName
and whose directory exactly matches the defaultActionType you specified on
the action model in the Create a new sub tab model for your tab in navigation-
actionModels.xml section on page 12-19. In this example the JSP would be
"mytab\list.jsp".
• You must name your JSP exactly the same as your action. In this example
both are named "list".
Objective
You want to customize the set of UI components (actions or other UI elements)
that the administrators of the site, organization or containers can manage using the
role-based visibility feature.
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 Windchill Business Administrator's Guide 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 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:
At the container level, you are managing the equivalent list presented when
configuring visibility by roles:
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• The behavior of user roles in Windchill
• The administration of ad hoc access control policies in Windchill
• The actions framework in the Windchill client architecture
• The navigation framework in the Windchill client architecture
• The management of XML file customizations
• The management of RBINFO file customizations
RoleAccessResource.rbInfo RBINFO Defines the labels to provide in the Uis for the actions
or UI components.Located in
<Windchill>/wtCustom/com/ptc/netmarkets/roleAcc
ess/.
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.
See the section on the The uic Element on page 12-33 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.
Regenerate your bundles. The name of the uic should be the same as the
constant for the entry in the resource bundle.
3. In <Windchill>/codebase/actions.xml, modify the create folder action by:
adding the attribute uicomponent="PROJECT_CREATE_FOLDERS"
<action name=" folder_create" checkaccess="true"
uicomponent="PROJECT_CREATE_FOLDERS">
Customization Points
Default Possible
Parameter Value values Req? Description
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.
Enabled true true | false N Whether or not this uicomponent will be shown in
the wizard and utilized by the system.
DefaultAll true true | false N The default visibility value for All Members.
DefaultManag true true | false N The default visibility value for Project Managers.
er The permissions are a union of all permissions
across all roles; if you set defaultManager to false;
you should also defaultAll to false, otherwise
managers will still have access through the
ALL_MEMBERS role.
DefaultGuest true true | false N The default visibility value for people in the Guest
role.
Guests are not technically members of the Project;
they are not unioned with the ALL_MEMBERS
role.
ManagerEnabl true true | false N Whether or not this uicomponent can affect the
ed manager role. Do not change this value in out-of-
the-box UICs. For customized UICs, you may
choose your own setting.
GuestEnabled true true | false N Whether or not this uicomponent can affect the
guest role. Do not change this value in out-of-the-
box UICs. For customized UICs, you may choose
your own setting.
runMethod - Java method N The method to run when the UIAccess is changed.
name This represents the name of a method that will be
run when a UIAccess element associated with this
UIComponent is updated.
The signature of this method must be:
void foo(WTPrincipal principal, WTContainer
container, boolean isRender)
The principal passed in will be the group or user on
which to operate. The boolean isRender is the
updated value for the UIAccess.
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.
runClass="com.ptc.netmarkets.roleAccess.StandardNmRoleAccessServic
e"
runMethod="modifyTeamPermissions"/>
The principal passed in will be 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
Additional Resources
Objective
Your users are not able to access tabs because the stickiness context is wrong.
Examples: Clicking on Library tab leads to the Product tab.
Background
Each tab maintains a sticky info in order to take the user back to the same page
they were on last time they visited the tab. It is possible for the stickiness info to
be corrupted somehow (e.g. Library tab having a sticky context object that is in a
Product results in the issue described in the problem statement – clicking on the
Library tab leads to the Product tab).
This issue should not occur during the normal course of navigating the UI, but it is
very easy to simulate the issue by manually manipulating the url.
One way to force this issue to occur is to visit the details page of an object in a
Product and add tab=library as a url parameter. This would cause the object in the
Product to be stored as the sticky object for the Library tab. Now clicking on the
Library tab will lead to the Product tab.
Solution
Clear the sticky info for the tab with the issue.
Prerequisite knowledge
To see or clear the sticky info for a particular user, you need to be logged in as the
user.
Note: Depending on which solutions are installed and the user’s role, you would
see a different set of tabs than what is shown in the screen shots.
For example, if clicking on the Library tab leads to the Product tab, the Library tab
sticky info should be cleared. So click on the “clear library tab” hyperlink. (or
click on “clear sticky info for all tabs” if you don’t mind clearing out all the
stickiness info for that user)
Notice both sticky context oid and sticky action should be blank after you’ve
cleared the sticky info.
Additional Resources:
• Windchill Client Architecture Action Framework Overview on page 12-2
This chapter describes how to gather data to be used in the user interface.
Topic Page
Data Acquisition Configuration Properties .............................................. Page 13-2
Acquiring Data via Info*Engine .............................................................. Page 13-9
NmObject Utilities ................................................................................. Page 13-15
13-1
Data Acquisition Configuration Properties
Objective
You want to configure how data is retrieved for a Windchill Client Architecture
table, tree or property panel.
Background
This document describes how you can configure Windchill Client Architecture
components to retrieve and process data, without writing framework-specific Java
code.
Windchill Client Architecture allows you to configure a means to get your
backing component data, and then a way to configure how this data is post-
processed to extract the properties that will actually be shown in the UI. What this
means is that you have a lot of flexibility regarding the kind of data you retrieve,
as long as it can be post-processed by the infrastructure.
Scope/Applicability/Assumptions
Specific considerations for each type of Windchill Client Architecture component
are covered in their respective sections within the Windchill Customizer’s Guide.
Intended Outcome
An understanding of what options are available to you to configure data
acquisition for a Windchill Client Architecture component.
Solution
Use the getModel, describeColumn and describeProperty tags to configure a data
source for your Windchill Client Architecture component.
Prerequisite knowledge
To apply this knowledge you need to have an understanding of the following:
• JSP expression language (EL)
• JSP tags
• Windchill Client Architecture overview
targetObject attribute JSP tag attribute A tag attribute that allows you to change
the "backing object"
Procedure - Extracting properties from data elements when using the getModel tag
If you configured your component using the getModel tag, you still need to tell
the Windchill Client Architecture framework how to extract each property that
will be displayed in the component from the resulting data elements. In many
cases Windchill Client Architecture can automatically figure out how to extract
these properties:
• Bean properties: If you are using an API that returns a Java bean, and you
intend to display a property in the UI that corresponds to a property of the
bean, the infrastructure can handle this automatically.
• Soft attributes: Windchill Client Architecture knows how to automatically
find soft attributes for your business objects, even if the objects you returned
do not know about the soft attributes.
• Existing Windchill Client Architecture extensions: Windchill Client
Architecture already has a rich set of logical "properties" which can augment
the business object or Info*Engine Element that you return.
Bean properties
Windchill Client Architecture handles Java beans in the same way that the JSP EL
does, meaning you can refer to a property name and the infrastructure will look
for a corresponding getter on your object. For example, if you have described a
table with a column like the following:
<jca:describeColumn id="foo" .../>
Then the infrastructure will look for a "getFoo" method on each result object that
it processes when it executes your getModel API. If the method isn't found, then
the infrastructure does not fail, but instead will simply return a null value, for the
UI component to process in whatever way it chooses. By default the UI
components just render a blank in this case.
You are not limited to simple properties of the bean. In fact, anything you can do
with the JSP EL can also be accomplished with Windchill Client Architecture. For
example, you can use the dot notation to refer to nested properties. In addition,
Windchill Client Architecture treats Map objects as beans, so if your API returns a
Map or has a nested Map property, you can refer to it just as if it had getter
methods. For complete information on what you can specify in bean notation,
refer to the documentation for beanutils, the core package that Windchill Client
Architecture uses to process bean properties.
targetObject
targetObject provides a complementary approach to bean-style notation to access
nested properties of objects. It is described in more detail below.
Soft attributes
Windchill Client Architecture can automatically look up the soft attributes for
your Typed business objects if you ask it to. If you have a soft attribute on your
part named "baz", and have added a column descriptor as follows:
<jca:describeColumn id="baz" .../>
Windchill Client Architecture will fail to find a bean property for "baz" on your
business object, but will not just give up. It will next try to see if "baz" could be a
soft attribute of the object. There are two ways that Windchill Client Architecture
can determine this:
• If "baz" corresponds to a logical attribute of the object type.
• If the component id is a soft attribute external form, such as IBA|baz
If Windchill Client Architecture is able to find a soft attribute definition for the
object, then it will go and fetch the object's value.
• Retrieval of soft attributes can be expensive, so if Windchill Client
Architecture determines a soft attribute retrieval is in order, it will get the soft
attributes for all objects in the data set at once.
Procedure - Using the targetObject configuration to change the "backing object" for a
component
targetObject allows the developer to manipulate the result set from a backing API
call, so that the infrastructure treats a property of each result object as the "row"
object rather than the result object itself. For example the following configuration
tells the infrastructure to use the "foo" property of the result object as the backing
object for the "bar" row:
<jca:describeColumn id="bar" targetObject="foo" .../>
Rule of thumb: Use targetObject with Windchill Client Architecture extension classes
The difference between the foo.bar and targetObject="foo" approaches is that
when you configure target object, the infrastructure treats the target object as if it
were the object returned by your backing API. When you use the bean-style
property configuration, the backing object for the API remains the row object that
the Windchill Client Architecture infrastructure interacts with. This difference
becomes significant when using Windchill Client Architecture extension classes
in particular -- these classes may base functionality on what they think the current
row object is, not just on what the specific property is that was requested in the
component configuration. For this reason, it is generally a good practice to use the
targetObject property when reusing a Windchill Client Architecture extension
class (typically a DataUtility implementation).
Customization Points
Refer to the Constructing and Rendering a Table Using the JSP Framework
section on page 14-23 and the Windchill Client Architecture Tree section on page
14-64 for details on the various tag customization points discussed in this
document
Sample Code
Refer to the Constructing and Rendering a Table Using the JSP Framework
section on page 14-23 and the Windchill Client Architecture Tree section on page
14-64 for more code samples.
Objective
You want to use an Info*Engine task to get the data for a Windchill Client
Architecture table component
Background
Windchill Client Architecture provides a getIeModel tag that works similarly to
the getModel tag, but that retrieves its data from Info*Engine. The tag interacts
with other Windchill Client Architecture tags just as getModel does. The
difference is that instead of specifying a service method, one specifies an “action”
that maps to an Info*Engine task.
Intended Outcome
A Windchill Client Architecture table that has its data backed by an Info*Engine
task
Solution
Use the Windchill Client Architecture getIeModel tag to configure a Windchill
Client Architecture table component
Prerequisite knowledge
Readers should be familiar with Info*Engine as well as with the basic Windchill
Client Architecture data acquisition concepts.
Solution Elements
getIeModel tag JSP tag Configures the task to use to get the data
Param tag JSP tag A tag from the ie tag library that supplies
parameters to the getIeModel tag
Note: Most of these parameter names can be reconfigured to some other name
using ie:params. See the Customization Points section below for details.
Customization Points
getIeModel attributes
The following are attributes of the getIeModel tag that can be customized:
action None Any valid task name Yes The name of the task to execute
form The current Name of a valid group No A group that contains form data for
request in the page VDB the task
parameters
Limitations
Currently there is no Info*Engine support for trees.
<h2>Test Search</h2>
<table>
<tr>
<th scope="row" align="right">Type:</th>
<td>
<input type="text" name="TYPE" value="${param.TYPE}"/>
</td>
</tr>
<tr>
<th scope="row" align="right">Additional criteria:</th>
<td>
<input type="text" name="WHERE" value="${param.WHERE}"/>
</td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit"
value="Search"/></td>
</tr>
</table>
<p>
<jca:renderTable model="${tableModel}"/>
Related Documentation
• Windchill Adapter Guide (Info*Engine)
Objective
You need to give each row in a Windchill Client Architecture table or tree a
unique identifier, and a persisted object identifier is either inappropriate or
unavailable.
Background
Left to their own devices, Windchill Client Architecture components assume that
each row object that they are processing is a Windchill Persistable object.
Components use the object identifier from the Persistable as a way to uniquely
identify the object for selection and hyperlinks.
If you run into a situation where the data returned by your query is not a
Persistable object, or the data does not map to a Persistable in an obvious way,
then you can implement an NmObjectUtility to provide the infrastructure a way to
uniquely identify your objects.
targetObject is preferable to NmObjectUtility
If the row objects expose an API that returns a supported object type, then you do
not need to write an NmObjectUtility. In this case, you can use the targetObject
configuration at the table and/or column level to tell the infrastructure what
property to use as the backing object for the row. The supported object types
along with additional information are documented in the Data Acquisition
Configuration Properties section on page 13-2.
If it is possible to modify the row objects to expose an API for targetObject, this
approach is considered a better practice than writing an NmObjectUtility, as it
means you have fewer dependencies on framework-specific code.
Intended Outcome
An implementation of the NmObjectUtility interface
Solution
Implementing an NmObjectUtility
Prerequisite knowledge
You need to have an understanding of the following:
• Windchill application context (“service.properties”)
• Windchill Client Architecture Overview
• Configuring Data Acquisition
• NmObjects Overview
An xconf file Configuration The file in which you will register your
file new NmObjectUtility
After adding the xconf entry, be sure to run the xconfmanager to propagate the
change to your installation.
NmCommandBean
Object that 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 will execute actions if they exist on the
request but it won't execute actions accidentally if the page is manually refreshed
and the form is resubmitted. It essentially carries the request and state information
from the Tomcat VM to the Method Server VM.
Interesting attributes:
• Context: the where. compcontext, parentContext, element context, etc are
used to determine what page is displayed and where actions are launched.
• oids : the objects that actions or pages apply to.
• requestData : all the state info about the page
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 javadoc for more info api usages.
NmOid
A Netmarkets version of a WTReference that hides some details of the different
reference types and provides helper apis to aid in caching. Furthermore, it is the
object that understands how to parse any string format from the request that
represents an object in the db.
NmSimpleOid
NmSimpleOid represents a non-persisted business object. Often it is used 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.
NmContext
NmContext represents a UI address of a page.
• 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"
Example NmContext string a document residing in a folder on a project's folders
page. Note that the $, ^, and !* are reserved separator characters.
"folder$list$OR:wt.projmgmt.admin.Project2:2343$OR:wt.folder.Su
bFolder:7195^VR:wt.doc.WTDocument:18913!*
This chapter describes how to customize information that is displayed in the user
interface.
Topic Page
Attribute Handling.............................................................................................14-2
Soft Attributes and SCAs ................................................................................14-21
Constructing and Rendering a Table Using the JSP Framework ....................14-23
Windchill Client Architecture Tree.................................................................14-64
Adding Custom Modeled Attributes to all Table Views.................................14-91
Attribute Tables...............................................................................................14-92
Generating the Name Attribute Server............................................................14-97
Partial Activation of JSCA ............................................................................14-102
Icon Delegates ...............................................................................................14-103
UI Validation.................................................................................................14-109
Customizing the Find Number Field .............................................................14-152
14-1
Attribute Handling
Objective
You want to render a UI component for an attribute of a Windchill object to either
capture the user’s input during Create/Edit or to display the existing value of that
attribute.
Background
In a Windchill client application, attributes of Windchill objects are rendered in 2
modes – the ‘input’ mode for Create and Edit and the ‘view’ mode (on the
Information pages, Tables, etc). The data-type of these attributes is restricted to
the Windchill supported data-types exposed in the Information Modeler and the
Attribute Manager. Standard data acquisition, translation, rendering and form
processing mechanisms are required to maintain consistent attribute handling
behavior across all client applications. The consistency is achieved by using the
JCA framework. This framework provides re-usable components for building the
UI components to represent attributes, from the server-side objects that represent
them. The framework also provides extension points for customization via the
ability to override the standard data-translation and rendering behavior. This
document describes the best practices for creating and rendering a HTML GUI
component to represent a Windchill attribute.
A data utility is used to create a GUI component for an attribute. The data used to
create this GUI component is a combination of the attribute and constraint
definitions, and the configurations listed in the Customization Points section on
page 14-12. The renderer for the GUI component generates the HTML for
rendering the component.
The Property Panel section on page 11-26 and the Constructing and Rendering a
Table Using the JSP Framework on page 14-23 describe how to configure an
attribute for being rendered in the client.
The GUI components and their renderers can also be used to represent attributes
that are not Windchill attributes like drawing a simple check-box on a page to
capture some input from the user.
GUI components can be simple components such as a text-box or composite GUI
components built using the simple components, like a component that uses a text-
box and 2 combo-boxes, as shown below:
Simple GUI component:
The components generated by this framework also have some built-in client-side
validations, based on the constraint definitions and the configurations.
Scope/Applicability/Assumptions
Applicability
This practice should be followed when developing clients that need to display the
following attributes:
• Attributes whose type is a valid Windchill soft attribute type.
– Boolean
– Integer
– Floating point number
– Floating point number with Units
– String
– Date & Time
– wt.fc.EnumeratedType
– URL
– WTOrgRef: At this time, the framework has support to display the value
of these types of attributes, but does not support the input/editing of those
values. The Windchill Product Structure Explorer provides the necessary
support to input values for these attributes.
– Classification Node
• Attributes whose type is any of the following native Java types:
– primitive boolean, java.lang.Boolean
– primitive byte, short, integer, long, java.lang.Byte, java.lang.Short,
java.lang.Integer, java.lang.Long
– primitive float, double, java.lang.Float, java.lang.Double
– java.lang.String
– java.sql.Timestamp
• Special Windchill attributes
Intended Outcome
Consistent attribute handling behavior (rendering, validation wherever applicable
and attribute processing) on any Windchill client that uses a given Windchill
attribute in a given mode.
Solution
Use the Windchill client framework for rendering attributes in a Windchill client
application.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• The Windchill soft attributes, Attribute Manager, Type Manager, constraints
that can be defined on attributes in the Type Manager.
• The InfoModeler and constraints that can be defined on attributes in the
InfoModeler.
• Basic knowledge of the Windchill Client Architecture
• The Windchill JSP ‘describeColumn’ , ‘describeProperty’ tags
• AllClients.xml and Windchill preferences for customizations
• The management of RBINFO file customizations
componentRB.rbInfo rbInfo
Form processing delegates java The classes that process the form data of
the OOTB GUI components.
return gui;
}
If custom UI behavior is required for the attribute, you are familiar with the JCA
GuiComponent that represents that attribute and the data held in this object is
sufficient to provide the rendering behavior you require, implement a custom
Renderer for rendering the GUI component outlined in the Implementing a GUI
component renderer section on page 14-10.
Example:
In this case you would write a custom renderer for the DateInputComponent.
If the desired behavior cannot be achieved by just implementing a Renderer, the
next alternative is to implement a GUI component for the attribute as outlined in
Implementing a GUI component section on page 14-11.
You may need to create a special form processing delegate if you are trying to use
custom GUI components. See the Wizard Processing section on page 15-19 and
Building Wizards to Create a Single Object on page 15-38 for information on how
to do this.
Attribute Type is Windchill supported type, but you need to modify the way it is rendered
Same as Attribute type is not a Windchill JCA framework supported type on page
14-6 except that you may need to implement a data utility only if you are creating
a custom GUI component.
Need to post-process the raw data returned by the core APIs before displaying it
Same as Attribute type is not a Windchill JCA framework supported type on page
14-6. You can post-process the raw data in the data utility before using it to create
the GUI component.
You may need to create a special form processing delegate if you are planning to
use custom GUI components. For example, you may want to generate a hidden
<Service name="com.ptc.core.components.descriptor.DataUtility">
<Option
serviceClass="com.ptc.core.components.factory.dataUtilities.Folder
edDataUtility"
requestor="java.lang.Object"
selector="location"
A note on cardinality:
Your safest bet is to use a "duplicate" cardinality. This will create a new instance
of the data utility each time one is requested.
Example:
The FolderedDataUtility is configured with cardinality "duplicate". This is
because the FolderedDataUtility is stateful, it does some multi-object querying in
setModelData, and then holds on to this data for subsequent calls to getDataValue.
Since the utility is stateful, you must create a new instance of the utility for each
table rendering request. By registering the data utility as "duplicate", application
context will instantiate a new data utility for you each time one is requested.
Data utility configuration entries can be added to any xconf file that ends up being
read in by application context (any "service.properties"-type file).
Example:
The OOTB Renderer implementation for rendering a GUI component for date &
time renders the component like this:
// render the combo box for the hours, the combo box for
the minutes and the time zone
…
}
}
2. Register your custom renderer. In your data utility, when creating the
GuiComponent in the getDataValue method, register this custom renderer as
your DateInputComponent’s renderer
DateInputComponent gui = new DateInputComponent();
…
gui.setRenderer(new MyDateRenderer());
…
It is recommended that when you implement a new Renderer, you extend the
AbstractGuiComponent base class.
The TLD is
$WT_HOME/WEB_INF/tlds/wrappers.tld
Customization Points
Windchill preferences
Parameter Default Value Possible Values Description
Default Value Display Mode (Site Pre-populate Do not display Mode of displaying the
level) default value in the
Pre-populate
‘Create’ and ‘Update’
Button modes
This applies to all
attributes.
Selection List Style (Site level) Buttons Buttons UI style for Discrete-
sets/Enumerated set
Dropdown List
elements
Local Time Zone(User) Time zone set on the All standard time Local time zone of the
server. zones user – will be used as the
time zone for the display
/ input of date values.
Display length of attribute values 30 Any number >= 0 Used to control the
in tables number of character’s
displayed when the
attribute’s value is
displayed on a table. This
is also known as the
truncation length of an
attribute value.
Display length of attribute values 30 Any number >= 0 Used to control the
in the info page number of character’s
displayed when the
attribute’s value is
displayed on an info
page. This is limited to
the top attributes panel
and the folder location
(for folder info pages).
Any table displayed on
an info page will be
based “Display length
for attribute value in
tables.” This is also
known as the truncation
length of an attribute
value.
Possible
Parameter Default Value Values Req? Description
=15/>
componentRB.rbInfo file
Possible
Parameter Default Value Value Req? Description
Additional Resources
See the following sections for more information.
• Building Wizards to Create a Single Object (on page 15-38)
• Building Wizards to Edit a Single Object (on page 15-90)
• Data Acquisition Configuration Properties (on page 13-2)
• Presenting Information in the UI chapter - various sections on tables (starting
on page 14-1)
• Property Panel (on page 11-26)
Attribute Description
Example:
TypeIdentifier type_x = ...;
AttributeTypeIdentifier ati = (AttributeTypeIdentifier)
IDENTIFIER_FACTORY.get("ALL_SOFT_SCHEMA_ATTRIBUTES_FOR_INPUT_TYPE"
,type_x);
Attribute Description
Objective
You want present the information in a tabular format and optionally execute
actions on the presented data.
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.
The following tables details the specific elements within a table.
Element Description
Title Bar The title bar area tells users what information is
displayed in the table. The table title bar is located
at the top of the table and may contain: a table title,
an object count, the Current View pulldown list,
and several action icons - Help etc.
Menu Bar Tables with many actions will display a menu bar.
Each menu title provides a pulldown list of actions.
Shortcut Tool Bar The shortcut tool bar displays a subset of actions
from the menu bar. These are actions that are
frequently used. The shortcut tool bar may be used
without the menu bar when a table contains few
actions.
Status Glyph Columns The status glyph column(s) convey status and
messaging information about individual objects in
the table.
Object Icon Column The object icon column displays the appropriate
icon for that object.
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.
Intended Outcome
Depending upon the configuration, Table can be displayed in different formats.
Following is a general layout of a Table:
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving HTML, JSP, JavaScript and Custom taglibs.
• Overview of Windchill Client Architecture tags.
• The actions framework in the Windchill client architecture.
• Configuring views.
• Data acquisition, Data Utilities, GUI component
Configure Table
<%@ 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/core"
prefix="wc"%>
The first thing the JSP page does is defines a table using the describeTable tag.
This tag creates a table descriptor object and assigns it to the page variable
specified by the var attribute. This allows the descriptor to be referenced in the
JSP using the JSP expression language (EL).
The table defines a type, in this case Project2. The type is optional, and is only
used to do some defaulting of values. In this example, it is only being used to
default the labels for model-based column ids.
The actionModel property indicates the name of the action model (from
actionmodels.xml) that should be rendered in the table's toolbar.
The columns in the table each have their own describeColumn tag. Each column's
cell values will be produced by a data utility.
Customization Points
Possible
Parameter Default Value Values Req? Description
scope - Can be (case- No The name of the scope to export the var
insensitive): attribute to.
‘page’, ‘request’,
‘session’ or
‘application’
scrollType java.lang.String Value that represents constants from the JSTableConstants class
under keys .JSTABLE_IMPL*
"default" - chooses the browser default
"D" = Dom based scrolling, the default for tables in popup wizard
pages.
Possible
Parameter Default Value Values Req? Description
scope - Can be (case- No The name of the scope to export the var
insensitive): attribute to.
“page” ,
“request”,
“session” or
“application”
scope Can be (case- No The name of the scope to export the var
insensitive): “page” , attribute to.
“request”, “session”
or “application”
viewAllLink - URL to the view all No Option to show a view all link at the
page. bottom of the table.
helpContext - Any java.lang.String No The help context for this table. No help
value icon will be displayed if no help
context is specified.
Here <describeTable> is the tag which is responsible for rendering the columns in
the table . The label of the column can be fetched from the resource file. For this
we need to make the entry in the rbInfo file and give the “key” as a label in the
<describeColumn> tag.
To add/remove columns in the Table, insert/remove describeColumn tag from the
describeTable tag. The column order is the order in which the columns are defined
using the describeColumn tag in describeTable tag in a JSP file.
Each column has a guiComponent corresponding to the value to be shown in the
column. Each guiComponent has a reference to renderer object that is responsible
for generating the html. To change the default renderer we need to change the
guiComponent or the renderer reference for that guiComponent. GuiComponent
are created using the dataUtility.
To hide a column, use “hidden” attribute in the <describeColumn> tag. When
true, the column will not be shown in the displayed page but can be used in sorting
and filtering. This allows custom sorting and filtering options. The default value is
false.
This code snippet will sort the column “name” at the page load time
(defaultSort="true"). As well as user can sort the column as and when required
(sortable=”true”).
This will generate the Table as follows:
Sorting Behavior
Sorting behavior differs in following scenario:
1. For Paging tables
<model name="fileMenu">
<model name="editMenu">
<action name="create" type="document"/>
</model>
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:
object.fileMenu.description=File
object.editMenu.description=Edit
The entries for the File and Edit actionModels would look like:
object.fileMenu.description.value=File
object.editMenu.description.value=Edit
Since "cross page functionality" is now provided which allows the user to select
multiple rows across multiple pages, the menu bar actions will now be applicable
to the rows across multiple pages.
On click of the “?” sign the pop up will open up which will show up the help for
the table.
The isInfoPageLink attribute overrides the default behavior of the column to add
or remove a hyperlink to the info page of the context object. The attribute is only
applicable for the name and number columns. By default the number is a
hyperlink to the info page and name is not.
Adding the link will produce the following results:
Displaying table data as hyperlink can also be achieved using a data utility. The
data utility can be configured in service.properties file.
The table currently displays the "Sample View" created in the configurable table
implementation. If more than one table view was implemented, then the current
view displayed would be either the first view on the list (alphabetically) or the
table view set in the getOOTBActiveViewName method.
Selecting "Customize…" from the current view list launches a pop-up displaying
the configurable table views. From there, additional table views can be added and
removed using the toolbar actions.
For each view in that list, there is an action to set that view as "active". By using
this action, any view can be set as the default.
Example
// Hide the name step
public boolean showSetNameStep(){
return false;
}
Example
public Class[] getClassTypes() {
return new Class[] { WTPart.class };
}
Removing Attributes
An attribute can be removed from any step by overriding the appropriate method
and returning false for the attribute's id.
Example
// Sorting on the info page action doesn't make sense, so it is
being removed
public boolean isAttributeValidForSortingStep(String key) {
return !key.equals(ColumnIdentifiers.INFO_ACTION);
}
Special Columns
The getSpecialTableColumnsAttrDefinition(Locale) method tells the
configurable view wizard about columns that it cannot find out about
automatically (this is what makes these columns "special"). Automatic columns
are discovered by looking up the global columns that map to each data type
returned by getClassTypes.
The getSpecialTableColumnsAttrDefinition method returns a list of
com.ptc.core.htmlcomp.createtableview.Attribute.AbstractAttribute objects. Each
one of these attributes represents a column that a user can choose to include in the
table view. The primary value of these attribute definitions is that they allow the
table view wizard to know how to present filter criteria for the column. For
example, if a column is represented by a BooleanAttribute, then the wizard knows
that to filter on this column, the user should select either true or false.
There are 5 concrete types of AbstractAttributes:
• BooleanAttribute - A column that contains a boolean value
• CustomAttribute - Not used by the Windchill Client Architecture
• DateAttribute - A column that contains a Date value
• TextAttribute - A column that contains a String value
• ListAttribute - A column that contains a list of predefined values
The IDs for the attributes returned here should correspond to the ids used to define
data utilities for the columns, if needed
Most columns will not need to be listed here. It is very unlikely that a table will
have more than a few special columns. Only add a column here if it is specific to
the table. A common exception to this rule is the Actions column. Since it is not
defined globally, you will need to add it here if you want that column.
Example
public List getOOTBTableViews(String tableId, Locale locale) throws
WTException {
// The list of all ootb views
List<TableViewDescriptor> ootbViews = new
ArrayList<TableViewDescriptor>();
columns.add(TableColumnDefinition.newTableColumnDefinition(ColumnI
dentifiers.FOO, /*lockable*/false));
columns.add(TableColumnDefinition.newTableColumnDefinition(ColumnI
dentifiers.BAR, /*lockable*/false));
criteria.add(TableViewCriterion.newTableViewCriterion(ColumnIdenti
fiers.STATE, OperatorConstants.EQUALTO,
ProjectState.RUNNING.getStringValue(), null));
criteria.add(TableViewCriterion.newTableViewCriterion(ColumnIdenti
fiers.ICON, OperatorConstants.EQUALTO,
AttributeHelper.getObjTypeKey(Milestone.class), null);
return ootbViews;
}
OR
<jca:describeTable id="someTable"
configurableTableId="someConfigurableTableId" ... >
Example
<jca:renderTable model="${tableModel}"
showCustomViewLink="false"/>
Example
<jca:describeTable var="tableDescriptor" id="my.table"
configurable="true" singleViewOnly="true" ... >
Configuring Tables - Linking the JSP Table to the Configurable Table Instance
Once the table is implemented, it needs to be registered in application context in
order for the infrastructure to find it.
Note that this will delete all user view information from the system, so it should
not be used in a production environment. In a production environment you will
need to delete the loaded ActiveViewLink and TableViewDescriptor individually.
This can be done while the system is running, and things should continue to work.
String result =
com.ptc.core.htmlcomp.components.TableViewBean.getCurrentView("car
ambola.appcontext.report");
It is recommended that you define customized attributes in a new file and then
register that file as follows in your site.xconf:
<AddToProperty
name="com.ptc.core.htmlcomp.createtableview.AvailableAttributesDig
To derive the list of available attributes, the available attributes factory first asks
your configurable table instance for the list of available types. Using this type list
it then builds a list of attribute definitions from those defined in
AvailableAttributes.xml for each type.
Debugging
To view debugging information about available attributes, set the following
Log4J properties:
log4j.logger.com.ptc.core.htmlcomp.createtableview.AvailableAttrib
uteFactory=TRACE
log4j.logger.com.ptc.core.htmlcomp.createtableview.AvailableAttrib
uteCache=TRACE
log4j.logger.com.ptc.core.htmlcomp.util.TypeHelper=TRACE
log4j.logger.com.ptc.core.htmlcomp.createtableview.labels=TRACE
To view a listing of available attributes for a given type, use the following report:
http://<machine
name>/<WindchillAppName>/netmarkets/jsp/carambola/createtableview/
availableAttributesReport.jsp
Attribute Labels
Any label defined in the AvailableAttributes.xml will be used first. After that the
com.ptc.core.htmlcomp.jstable.JSStandardColumnDescriptorFactory is used. The
JSStandardColumnDescriptorFactory can retrieve attribute labels for certain
common attributes. It is not recommended to edit the
JSStandardColumnDescriptorFactory to accommodate attribute labels for
Windchill Client Architecture table views.
If the JSStandardColumnDescriptorFactory can not find a label for the attribute, it
will attempt to find a label in com.ptc.core.ui.componentRB using the JCA id as
the key. If it still can not find a label for the attribute, it will use the label retrieved
from introspection.
• Map Tag
Defines attribute id mappings between legacy JS Tables and Windchill Client
Architecture ids. JS ids are defined in JSPropertyDataConstants and are
needed to maintain backward compatibility with older CADX tables.
Windchill Client Architecture ids should match those used for data utilities.
Child of the Class tag.
• Class Tag
Encompasses attribute definitions for the declared type.
name The type. This can be either a hard or soft type and
should be formatted as a TypeIdentifier. Required.
<Class name="wt.part.WTPart">
• Attribute Tag
Defines an attribute for the given type causing this attribute to be available to
users when they are creating and editing table views. Child of the Class tag.
type The type of the attribute. This will affect what kind of
criteria is available when creating filter criteria.
• Include Tag
Includes the attribute definitions defined within another Class tag. Child of
the Class tag.
• Label Tag
Defines a key and a resource bundle or EnumeratedType to retrieve the
attribute's label from. Child of the Attribute tag.
Review the process used to find attribute labels and ensure the label for your
attribute is defined in one of those locations.
• The column name in my table is incorrect
Try enabling the common components label logging:
log4j.logger.com.ptc.core.components.labels=TRACE
It is up to the data utility defined to retrieve the label for the table column
header.
• When I edit my OOTB view, my attribute does not appear as a selected
column despite being included in the active view
If you've edited your OOTB view definitions, you need to reset your table
views. Otherwise it is possible that the table view class is loading OOTB
views with incorrect ids. Ensure you are using the ids defined in
DescriptorConstants.ColumnIdentifiers.
You must specify the jsp name in the "viewAllLink" parameter. When the user
clicks on "View All" in the Table footer, the user is taken to the JSP mentioned in
this parameter and that JSP would display list of all items in the Table. All the
Home -> Overview tables use "viewAllLink" parameter. You can disable the
footer by adding "jcaPageModel.setPageFooter("false")" in the jsp after the
include of begin.jspf.
Limitations
None.
<fmt:setLocale value="${localeBean.locale}"/>
<fmt:setBundle basename="com.ptc.carambola.carambolaResource"/>
<fmt:message var="tableName" key="PART_TABLE_LABEL"/>
<fmt:message var="actionsName" key="ACTIONS_COLUMN_LABEL"/>
<%-->Get a table model using our descriptor and query command, assign model to page
variable tableModel<--%>
<getModel var="tableModel" descriptor="${tableDescriptor}"
queryCommand="${queryCommand}"/>
Folder browser table for This table can be accessed by JSP (For Product tab):
Project, Product, Organization clicking on “Folders” subtab <Windchill>/netmarkets/jsp/pr
from oduct/listFiles.jsp
Program/Product/Project/Orga
nization tab.
Other Resources
• Adding Actions and Hooking Them Up in the UI chapter (starting on page
12-1)
• Customizing the UI with Ajax (on page 11-4)
• Data Acquisition Configuration Properties (on page 13-2)
Objective
You want to implement a Windchill Client Architecture Tree for the display of
Windchill business objects.
Background
A tree view is used to display hierarchical data organized in the form of a tree. In
other words, 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.
Following are the few key salient features of a Windchill Client Architecture Tree
with respect to a Windchill Client Architecture Table
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.
Scope/Applicability/Assumptions
It is assumed that your <MyPage>.jsp file in which you are implementing the
Windchill Client Architecture tree includes “/netmarkets/jsp/begin.jspf” file and
“/netmarkets/jsp/end.jspf” files
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:
• JSP, JavaScript and Custom taglibs.
• The actions framework in the Windchill client architecture.
• Windchill Client Architecture Table component.
• Configuring views.
• Data acquisitions, Data Utility, GUI component.
NmCommandBean cb = getModelContext().getNmCommandBean();
WTPart part;
NmOid oid = cb.getPageOid();
if (oid == null) {
log.debug("No oid found in request, trying GOLF_CART");
part = getGolfCart();
}else {
if (!oid.isA(WTPart.class)) {
throw new ClassCastException("Expected part, but was: "
+ oid);
}
part = (WTPart)oid.getRef();
}
if (part == null) {
log.debug("Couldn't get part");
return null;
}
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.
In the given example, the method first checks to see if the configSpec is not
initialized from the previous method. If it isn’t, then it calls the
getDefaultConfigSpec method, which gets the default ConfigSpec from the
if (configSpec == null) {
configSpec = getDefaultConfigSpec();
}
------
------
<%@ include file="/netmarkets/jsp/util/end.jspf"%>
Configure Tree
This can be structured into three steps
1. Creating tableTree descriptor object using describeTableTree tag.
a. This tag creates the tableTree descriptor object and assigns it to the page
variable specified by the var attribute
b. The id attribute stores the identifier for this table descriptor.
2. Defining the component model by passing the tableTree descriptor into the
getModel tag.
a. This takes the tableTree descriptor to get the tableTree data and returns a
model object that will be used to render the tree
b. The tableTree descriptor variable must be specified in the descriptor
attribute.
c. The treeHandler attribute is used to specify the JAVA API service class
that retrieves the tree data.
<jca:getModel var="wcaDemo_tree_model4"
descriptor="${wcaDemo_tree_descriptor4}"
treeHandler="wcaDemoTreeHandler1"/>
3. Rendering the tableTree by passing the model object into the renderTableTree
tag.
a. The variable for the model object specified in the getModel tag gets
passed into the model attribute.
b. If the model attribute is not specified, then a NmHTMLTableTree must
be specified using the tree attribute instead.
jca:renderTableTree model="${wcaDemo_tree_model4}"
showTreeLines="true" />
----
----
<!-- TREE CONFIGURE START -->
<%-->Build a descriptor and assign it to page variable
treeDescriptor<--%>
<jca:describeTableTree id="wcaDemo_tree_example4"
var="wcaDemo_tree_descriptor4"
type="wt.part.WTPart"
label="${treeName}"
nodeColumn="number"
configurable="true"
expansion="full"
helpContext="DEFAULT_HELP_PAGE"
disableAction="false"
summary="test">
<jca:setComponentProperty key="selectable"
value="true"/>
<jca:setComponentProperty key="actionModel"
value="wcaDemo_tree_toolbar"/>
<jca:describeColumn id="number" />
<jca:describeColumn id="name" />
</jca:describeTableTree>
Customization Points
scope request Can be (case- No The name of the scope to export the
insensitive): var attribute to.
“page”, “request”,
“session” or
“application”
selectionObject No Deprecated
scope request Can be (case- No The name of the scope to export the
insensitive): “page” var attribute to.
, “request”,
“session” or
“application”
scope request Can be (case- No The name of the scope to export the
insensitive): “page” var attribute to.
, “request”,
“session” or
“application”
var="wcaDemo_tree_descriptor2"
type="wt.part.WTPart" label="${treeName}"
nodeColumn="name" expansion="one">
-------------
</jca:describeColumn>
</jca:describeTableTree>
dataUtilityId="your_column_data_utility_id" />
5. You can control the visibility of “Customize …” link in the view drop down
by using “showCustomViewLink” attribute of renderTableTree tag. “false”
hides the link whereas “true” shows the link which is the default behavior.
<jca:renderTableTree model="${wcaDemo_tree_model6}"
showCustomViewLink ="true" />
6. If the tree has only one view and you want to modify the columns (visibility,
order etc), you need to set “singleViewOnly” attribute of describeTableTree
tag to true.
<jca:describeTableTree id="wcaDemo_tree_example5"
var="wcaDemo_tree_descriptor5" type="wt.part.WTPart"
label="${treeName}" nodeColumn="number"
configurable="true" singleViewOnly ="true"
------
configurableTableId="wcaDemo_tree_viewId1">
--------
Windchill Client Architecture Tree with and without Tree Lines & Count
Using this you can set the number of rows of a tree in a page and this will be
applicable to all the trees across Windchill system. Its usage is highly
discouraged and in the coming release this property will be deprecated.
For popup pages, the default scrollType is DOM. But, it is recommended to use
Viewport. Also. it is recommended to use "Viewport" scrollType in case of non
editable form fields.
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
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
Objective
This documentation provides developers with the information required for
implementing the attributes table component for a given business object in
information page.
The Attribute Table component was developed to give the Windchill products
consistency for displaying all necessary attributes of any object in details page.
The component should also make developing attributes table much easier. Using
this component, a developer only needs to configure attributes tables page only,
while the main layout of the page is provided by the component.
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
documentation 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.
Packaging
The attributes table component itself is located in the Windchill vob under the
CommonComponents module:
ProjectLink\NetMarkets\src_web\netmarkets\jsp\object\attribute.jsp
(the default attributes table)
ProjectLink\NetMarkets\src_web\netmarkets\jsp\util\
showSoftAttribute.jsp (the attributes table component)
codebase/netmarkets/jsp/document/attributes.jsp
codebase/netmarkets/jsp/part/attributes.jsp
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>
The attribute values are based on logical attribute mapping using the mechanism
in place for type instances. For a given object type, you can see what the logical
attribute names are by using the LogicalAttributes.jsp. This JSP can be accessed
from a running Windchill build; http://<machine>/<Windchill-app-
name>/meta/LogicalAttributeReport.jsp
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"
selector="Attributes"/>
<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" />
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>
3. Test your new jsp. The icons from the Home page or from the Folders page
should lead to the new info page servlet. The URL will look something like
this:
http://<machine>/<WindchillAppName>/servlet/InfoPage?oid=OR:wt.
part.WTPart:62028
Objective
You want to make the name attribute server generated.
Background
This section will describe making the name attribute server generated. This
attribute is not server generated out of the box. It will make the name attribute
behave exactly as the number attribute. This means the name attribute will also
respond to other OIRs that only apply to number out of the box, including
ServerPreGenerated and Immutable.
Scope/Applicability/Assumptions
Assume you have a need to have the name attribute be server generated.
Intended Outcome
The name attribute is server generated for all objects that have the
‘ServerAssigned’ constraint specified in the OIR for ‘name’.
Solution
Create your own custom DataUtility for the name attribute and set up the required
properties.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Data Utilities
• GUI Components
• Object Initialization Rules
Solution Elements
RuleConfigurableTypeAttribute. Configuration Contains the rule configurable attribute lists for each
properties object type.
codebase/com/ptc/core/rule/server/delegate/init/Rul
eConfigurableTypeAttribute.properties
GeneratedNameDataUtility Java class The new Data utility that will be created during this
procedure to enable Name to support server
generation.
NumberDataUtility Java class An out of the box data utility that knows how to
handle server generation for the number attribute.
2. Find your object type. For this example we are looking for WTDocument and
out of the box we have:
wt.doc.WTDocument=number,lifeCycle.id,lifeCycle,teamTemplate,te
amTemplate.id,folder.id,organization.id
3. Notice that name is not an attribute that is available for rules so we need to
add it in. In your site.xconf file add the following:
<Configuration
targetFile="codebase/com/ptc/core/rule/server/delegate/init/Rul
eConfigurableTypeAttribute.properties">
<Property name="wt.doc.WTDocument"
default="name,number,lifeCycle.id,lifeCycle,teamTemplate,tea
mTemplate.id,folder.id,organization.id"/>
</Configuration>
<Arg>{GEN:wt.enterprise.SequenceGenerator:WTDOCUMENTID_seq:10:0
}</Arg>
</AttrValue>
Note: For this purposes of this demonstration we will reuse the number generator
that exists out of the box. You will probably want to replace this with your own
custom generator.
See the online help for the Object Initialization Rules Administrator for additional
information.
import com.ptc.core.components.descriptor.DescriptorConstants;
import
com.ptc.core.components.factory.dataUtilities.NumberDataUtility;
2. You will then have to modify the UIs for Document that display this attribute
to include “documentName” instead of “name”.
In the file createDocumentSetAttributesWizStep.jsp change
<jca:describeAttributesTable var="attributesTableDescriptor"
...
<jca:describeProperty id="name" htmlId="NameInputId"/>
...
</jca:describeAttributesTable>
To:
<jca:describeAttributesTable var="attributesTableDescriptor"
...
<jca:describeProperty id="documentName" htmlId="NameInputId"/>
...
</jca:describeAttributesTable>
Customization Points
None.
Limitations
Since Number is a String attribute this quick customization is only relevant for
generated attributes of String Type that do not have a discrete set defined.
Packaged Samples
• com.ptc.carambola.customization.examples.wizard.GeneratedNameDataUtility
Additional Resources
If you want to test how a table works with JSCA vs JCA, you can toggle between
the two with a URL parameter.
If a developer wishes to test to see how a table works with JSCA vs JCA we have
also provided a url param that can be added to toggle the table between JSCA and
JCA. See example below:
Example:
http://machinename.ptcnet.ptc.com/Windchill/netmarkets/jsp/user/li
stCheckedOutWork.jsp?useJSCA=true
The useJSCA URL paramter name is case sensitive but the value is not case
sensitive and it will accept any form of true and false. It will also accept 1 for true
and 0 for false.
JSCA is not enabled by default. You can use the url param above to test single
pages. If you prefer to turn JSCA on as it will be when we ship you can modify the
file
windchill\codebase\WEB-INF\tlds\components.tld
and remove the default that has been temporarily specified to turn jsca off
(remove the line in bold below):
<attribute>
...
<name>useJSCA</name>
<required>false</required>
<type>boolean</type>
<default>false</default>
</attribute>
Note: Old Netmarkets architecture Tables and Trees (those that were not
converted to JCA) are currently using the JSCA rendering and do not at this time
support any methods of going back to the JCA rendering. The current
recommendation is that if you need an old legacy table to use JCA instead of
JSCA you will need to convert the table to JCA and use the tag attribute as
described above.
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 in Rational Rose. This icon
will be used when an object of this type is displayed. In case of soft types, the
Type Manager allows the user to associate an icon to be used to represent this soft
type in the UI. If the icon specified is an invalid or blank, the icon of the parent
type is used. This behavior is accomplished using IconDelegates.
However, there are cases where the icons are determined dynamically by other
factors, such as attributes on the object. The following table shows the OOTB
IconDelegates available for some Windchill Types.
wt.part.WTPart com.ptc.windchill.enterprise.part.commands.delegate.
WTPartIconDelegate
wt.epm.EPMDocument wt.epm.identity.EPMDocumentIconDelegate
wt.doc.WTDocument wt.doc.DocumentIconDelegate
If the user needs different icons on types (other than the OOTB) or for his own
modeled/soft types, he 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 able to view the icons defined by his IconDelegate for the respective
Windchill type objects.
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:
Solution Elements
<Property>
<!-- This attribute is populated by the SCA|objectIcon
function -->
<LogicalForm>objectTooltip</LogicalForm>
<ExternalForm>NPA|objectTooltip</ExternalForm>
</Property>
b. This API returns the localized tooltip value that need to be shown for the
icon.
@Override
protected boolean inflateRequired() {
boolean need = super.inflateRequired();
TypeInstance ti = getTypeInstanceObject();
if(ti != null && !need){
//check you necessary attributes in TypeInstance
// to determine to inflate it or not.
}
}
return need;
}
@Override
protected void initAttributes(Set<AttributeTypeIdentifier>
attributes) {
super.initAttributes(attributes);
//add your attributes here
}
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){
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.
• You want to determine whether or not a user can proceed to the next step in a
wizard or whether the entire wizard may be submitted, based on the data
entered by the user in that wizard.
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
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.
• Post-Select Validation - After a user selects an action, you want to determine
whether or not the target object is in a certain lifecycle state before allowing
the action to proceed.
• Post-Submit Validation - After a user enters data in the first step of a wizard
and tries to navigate to the next step, you want to determine whether or not the
information entered on the first step is valid before allowing them to proceed.
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.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• The actions framework in the Windchill client architecture.
• The Application Context or service.properties mechanism for registering
delegates.
• A basic familiarity with the NmCommandBean and its methods will be
helpful.
• The validation service is very generic in nature. It does not provide the APIs
you’ll need in order to determine whether or not something is valid. The
service will provide your validators or filters with the context data and form
data you need to determine whether or not a UI Component is valid. But you
will need to know what to do with that data in order to apply your validation
business logic.
The Additional Resources section below includes references to many or all of
these subjects.
Solution Elements
In addition to the solution elements involved in UI Validation, this section also
contains some definitions of key terms (in bold italic).
StandardUIComponentValidation Java class Often referred to as the validation service. This is the
Service 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.
ValidationFilter Java This is the interface that all filter implementations need
interface to implement. However, filters should not implement
this interface directly. Rather, they should extend
DefaultSimpleValidationFilter or
DefaultUniversalValidationFilter.
Each UI component can have zero to many filters
associated with it. Typically, a filter will contain generic
validation logic that could apply to multiple UI
components. For validation logic that is specific to a
single UI component or a small set of UI components, a
validator is typically used.
There are two categories of filters: simple filters and
universal filters. Simple filters are applied on a
component-by-component basis. In other words, you
have to choose which UI components the logic in a
simple filter will apply to. Conversely, universal filters
are applied to all UI components, which means you have
to choose which UI components the logic in a universal
filter *does not* apply to.
Filters are called by the validation service to determine
the validation status for a specific UI component.
Customizers and application developers should not have
to interact directly with this class.
Client Infrastructure 1
Validation Service
Key
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.
Cache of invalid
Client Infrastructure components for the
1
installed solutions
2a
Validation Service
Key
Cache of invalid
Client Infrastructure components for the
1
installed solutions
2a
Validation Service
2b
Role-Based UI Service
Key
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.
Cache of invalid
Client Infrastructure components for the
1
installed solutions
2a
Validation Service
2b
2c
Role-Based UI Service
Applicable Filters
Key
Cache of invalid
Client Infrastructure components for the
1
installed solutions
2a
Validation Service
2b
2c
Role-Based UI Service
2d
Validator
Applicable Filters
Cache of invalid
Client Infrastructure components for the
1
installed solutions
2a
3 Validation Service
2b
2c
Role-Based UI Service
2d
Validator
Applicable Filters
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.
d. Get the validation status from the validator, if there is one associated with the UI
component.
3. Return the validation result or validation result set to the client infrastructure.
Client Infrastructure 1
Validation Service
Key
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.
Client Infrastructure 1
Validation Service 2
Validator
Key
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
displayed. If the status is “denied”, the user is redirected to the previous page, and
Client Infrastructure 1
Validation Service 2
Validator
Key
Client Infrastructure 1
Validation Service
Key
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.
If there is not a validator registered for the action, the user is permitted to move to
the next step or submit the entire wizard. Otherwise, if there is a validator
Client Infrastructure 1
Validation Service 2
Validator
Key
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
“denied”, the user restricted from moving to the next wizard step or submitting the
Client Infrastructure 1
Validation Service 2
Validator
Key
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);
}
if (logger.isDebugEnabled()){
logger.debug("EXITING MySolutionGroup.getInvalidKeys");
}
return invalidList;
}
}
If you’re creating a validation key for an attribute, simply use the descriptor ID
used for that attribute in the Windchill client architecture. For example, to create a
validation key for the attribute whose descriptor ID is “iteration”, you would call
UIValidationKey.newInstance(“iteration”);
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="…/>
<includeFilter name="problemReportStatus" />
</action>
...
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.
Creating a Validator
Creating a validator class should be fairly simple. All you need to do is create a
class that extends com.ptc.core.ui.validation.DefaultUIComponentValidator.
The class below represents a skeleton for a simple validator class.
package com.ptc.windchill.enterprise.myPackage.validators;
import com.ptc.core.ui.validation.DefaultUIComponentValidator;
return resultSet;
}
@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">
<Option requestor="null" serviceClass="[your fully-qualified
Validator class]"
selector="[action name/attribute descriptor ID]" />
</Service>
• 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.
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.ChangeMgmtCreateWizardsVali
dator that we want to register for create actions, but only if the action is to create
a Problem Report.
We could look at the actions.xml entry above and see that the create action for a
Problem Report is actually defined for an objecttype whose name is
problemReport and, more importantly, whose class is
wt.change2.WTChangeIssue.
By using that class value from actions.xml as the requestor attribute in our
properties entry, we can tell the validation service that we only want to register
our validator
(com.ptc.windchill.enterprise.change2.validators.ChangeMgmtCreateWizardsVal
idator) for create actions whose object type is wt.change2.WTChangeIssue, like
this:
<Service context="default"
name="com.ptc.core.ui.validation.UIComponentValidator">
<Option
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
Registered validators:
pasteAsCopy ->
com.ptc.core.foundation.saveas.validators.PasteValidator
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. See Creating a Validator on page 14-139 for details.
UIValidationStatus.NOT_VALIDATED);
return result;
}
@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. See Creating a Validator on page 14-139 for details.
UIValidationStatus.NOT_VALIDATED);
return result;
• The checkAccess APIs should NOT be used to see if the user has a specified
permission, unless the intent is that an exception is to be propagated to the end
user. If the NotAuthorizedException is caught and does not result in a user's
action failing due to the lack of access rights, auditing of the exception should
be disabled. See the Javadoc for more information.
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.
There are a few things you can do to avoid this scenario. The first is to check and
make sure that the values you're getting from UIValidationCriteria are not null. If
a value is null, log a warning, and call super.[whatever method you're
implementing](key, criteria, locale);.
The other thing you can do is when performing comparisons, use the .equals
operation on the "expected" value. For example:
if
(ComponentType.WIZARD.equals(validationCriteria.getComponentType()
)
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)
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 accordance
* with the terms of the license agreement.
package wt.part;
import java.lang.String;
import wt.part.ValidateFindNumbersDelegate;
import wt.part.WTPartUsageLink;
import wt.util.WTException;
//##end validateFindNumbers%43C6C7F300E8.body
}
Topic Page
Windchill Client Architecture Wizard ..............................................................15-2
Wizard Processing...........................................................................................15-19
Building Wizards to Create a Single Object ...................................................15-38
Building Wizards to Edit a Single Object .......................................................15-90
15-1
Windchill Client Architecture Wizard
Objective
You want to create or perform an operation on object(s) by collecting information
step by step.
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. 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 a
single step or multiple steps. Each multiple steps wizard will have navigation
buttons (BACK / NEXT) at the bottom, which you can use to navigate from one
step to another.
A clerk is a user interface consisting of a tab control that has two or more tabs.
Data can be entered and the user can complete tabs in any order. A user may
freely move from one tab to another, even if the current tab is not complete. A
clerk is not meant to guide users sequentially through a task, and is typically used
for frequent and easily accomplished tasks.
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”.
Multi-Step Wizard
Multi-Step Clerk
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.
• Scrolling is enabled for table inside wizard as well as table inside picker.
• 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
Solution
Use a Wizard or Clerk component.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development, which involves HTML, JSP, JavaScript and Custom
taglibs.
• Overview of Windchill Client Architecture tags.
• The actions framework in the Windchill client architecture.
• Action validation framework.
Solution Elements
<your_wizard_step>.jsp jsp The jsp file, which contains contents of the wizard step.
<*-actions>.xml xml The actions for the wizard as well as each wizard step are
defined in this XML file.
actionmodels.xml xml The models for the list of buttons, to be displayed at the
bottom of the wizard (i.e. the navigation area) are
defined in this XML file.
<resourceBundle>.rbInfo rbInfo This is another option where you can specify locale
specific Strings and properties for wizard step and
wizard actions.
formProcessorController java The java class, which will be executed after the wizard,
is submitted. The wizard framework will pass on the
data / information to this java class.
<action name="affectedAndResultingItemsStep">
<command windowType="wizard_step" />
</action>
</objecttype>
<jca:wizard >
<jca:wizardStep action="defineItemWizStep" type="object"/>
<jca:wizardStep action="setAttributesWizStep" type="object" />
<jca:wizardStep action="affectedAndResultingItemsStep"
type="changeTask" />
</jca:wizard>
Define a Clerk
Defining a clerk is exactly same as defining a wizard, the only difference in the
case of a clerk is that you define the type as "clerk".
<jca:wizard type="clerk">
<jca:wizardStep action="defineItemWizStep" type="object"/>
<jca:wizardStep action="setAttributesWizStep" type="object" />
<jca:wizardStep action="affectedAndResultingItemsStep"
type="changeTask" />
</jca:wizard>
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.
Specify localized Strings / properties for wizard step and wizard actions
changeTask.create.description.value=New Change Task
changeTask.create.description.comment=Used as the label for the
create action
changeTask.create.title.value=New Change Task
changeTask.create.title.comment=Used as the title for the create
action
changeTask.create.tooltip.value=New Change Task
changeTask.create.tooltip.comment=Used as the tooltip for the
create action
changeTask.create.icon.value=../../wtcore/images/task_create.gif
changeTask.create.icon.comment=DO NOT TRANSLATE
Customization Points
This section contains the following topics:
• <action>.xml attributes
• <wizard> tag attributes
• <wizardStep> tag attributes
• Providing user defined buttons to Wizard
• Providing user defined form processor controller
• Providing server side validation before / after processing a wizard step
• Loading the wizard step content when it is visited
• Marking a wizard step as “required”
• Hiding a wizard step
• Displaying the hidden / dynamic step at runtime
• Providing user defined SUBMIT function
• Providing client side validations before a wizard step is displayed
• Providing client side validations after a wizard step is finished
<action>.xml attributes
Possible
Parameter Default Value Values Req? Description
Possible
Parameter Default Value Values Req? Description
buttonList “DefaultWizard Any String No The action model containing the list
Buttons” of buttons to display in the wizard.
The default set is the
DefaultWizardButtons action model.
Possible
Parameter Default Value Values Req? Description
Every button in the actionmodel should have a corresponding entry for its action
in actions.xml file. If there is a separate java class written to render that particular
button, than you can specify the name of that class and its method (which contains
the rendering code) using the “class” and “method” attributes of <command> tag.
For example:
<action name="revertButton" id="PJL_wizard_revert_to_default">
<command class="" method="" windowType="page"
url="javascript:revertToDefault()"/>
</action>
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 15-19.
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.CreateMu
ltiPartNameNumberValidator" />
</Service>
You can configure the wizard such that the content of any wizard step is not
loaded when the wizard is first initialized and loaded. You can load the contents
of a wizard step when you try to visit that step. You may need this feature when
the step is dependant on information gathered from a previous step.
You can use “preloadWizardPage” attribute of <action> tag to achieve this. By
default, the value of this attribute is “true”. For e.g.
<action name="setClassificationAttributesWizStep"
preloadWizardPage="false">
<command windowType="wizard_step"/>
</action>
Note: In the case of a clerk, all the steps will be loaded by default. The clerk does
not have conditional display of steps (i.e. hidden steps), so all the steps would be
preloaded.
You can also mark a wizard step as “required” at runtime. You need to use a
javascript function called “setStepRequired” which is defined in wizard.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 e.g.
<script src="/netmarkets/javascript/components/wizard.js"></script>
<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>
To implement first way of hiding a step, you can make use of the “hidden”
attribute of <action> tag. For e.g.
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 wizard.js file. You need to pass the “id” of the
Note: Clerk does not make 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
<script src="/netmarkets/javascript/components/wizard.js"></script>
<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>
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>
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 e.g.
<%@ 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>
Packaged Samples
• Wizard example one (can be accessed through wizard actions on table
examples):
<Windchill>\netmarkets\jsp\carambola\customization\examples\
wizard\newWizardExampleOne.jsp
Objective
You have created a JSP wizard to gather information from a user about one or
more object(s). You now need to create the code to process that information and
perform a database operation(s) on the object(s).
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 doPost() method of the WizardServlet. 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 performs
an RMI call to a FormProcessorController class in the MethodServer.
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 15-38 and Building
Wizards to Edit a Single Object on page 15-90 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.
Intended Outcome
Perform a database operation(s) related to one or more Windchill object.
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
WizardServlet Java class; runs in the servlet This is the class to which wizard form data
container gets posted and which sends the response
page sent back to the browser after
processing completes.
Runtime location:
<WT_HOME>/srclib/CommonCompone
nts-web.jar
ObjectBean Java class; runs in the A container for the form data specific to a
Method Server specific target object and the data common
to all objects. Provides methods to retrieve
the form data for a given object.
Runtime location:
<WT_HOME>/srclib/CommonCompone
nts.jar
ProcessorBean Java class; runs in the A container for ObjectBeans that knows
Method Server which ObjectBeans should be processed
by the same processor instance and the
order in which they should be processed.
Runtime location:
<WT_HOME>/srclib/CommonCompone
nts.jar
FormResult Java class; runs in the A class used to pass method results
Method Server and client between server methods and from the
server to the WizardServet.
Runtime location:
<WT_HOME>/srclib/CommonCompone
nts.jar
The framework generates object handles on name attributes for you in one of two
ways:
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
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
it's 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 DefaultFormProcessorController will call
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:
6 ProcessorInstance2.postProcess(O none
bjectBeans in Processor Bean 2)
7 ProcessorInstance1.postTransacti none
onProcess(ObjectBean in
Processor Bean 1)
8 ProcessorInstance2.postTransacti none
onProcess (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
Specify the processor class for the wizard on the wizard action
You specify the ObjectFormProcessor class in the <command> subtag of the
<action> tag for the wizard. Your action tag will be contained in a *actions.xml
file.
Here is an example of how you would specify the CreateDocFormProcessor class
as your processor.
<action name="create">
<command
class="com.ptc.core.components.forms.CreateObjectFormProcessor"
windowType="popup" />
</action>
The hidden input field will be generated for you by the AbstractRenderer
automatically. If the field is associated with a step or table row that has an
object handle, that object handle will be embedded in the HTML name
attribute of the hidden field. If you choose to return a GUI component that
does not extend Abstract GuiComponent, your GUI component and renderer
would have to know how to render the necessary hidden field.
• You can include a hidden field for your delegate directly in your jsp file.
However, one of the first two methods is preferred because it encapsulates the
hidden field with its associated HTML input fields.
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 15-33.
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.
Additional Resouces
Objective
You need to develop a wizard to capture user input and from that input create a
Windchill business object in the database.
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 Prerequisite knowledge section of this topic on page 15-41.
This document builds upon that information to describe how to develop and
process wizards designed specifically to create Windchill objects. It will tell you
how to use out-of-the-box components as building blocks to create your own
wizards. Components you will typically make use of are:
• action definitions for wizard steps that are common to multiple wizards
• jsp and jspf files for wizard steps that are common to multiple wizards
• custom tags for managing wizard data and displaying elements on the page
• Java classes for processing the wizard data after the user submits the wizard
Scope/Applicability/Assumptions
Assume you have created a custom Windchill business object class or soft type
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 you can ignore
such implementation details.
This document describes the reusable common components upon which most
Windchill create wizards are based. 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 the components described herein. These class-specific
components are built on top of the common components described in this
document. A discussion of those class-specific components is beyond the scope
of this document.
Be aware that you do not necessarily need to develop your own wizard to create
instances of a custom type. If your type is a modeled or soft subtype of a
Windchill business class for which a wizard with a type picker is already
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.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Java programming
• Basic web development using JSPs , custom tags, and HTML forms
• How to create modeled or soft Windchill business object types.
See the following chapters in the Windchill Customizer’s Guide for more
information on creating your business object classes using the Information
Modeler and Rational Rose:
– Getting Started With Windchill Customization chapter on page 3-1
– Modeling Business Objects chapter on page 4-1
– System Generation chapter on page 32-1
– Developing Server Logic chapter on page 36-1
– See the Type and Attribute Manager chapter of the Windchill Business
Administrator’s Guide for more information on creating soft types and
attributes.
• The use of actions to launch jsp pages and wizards.
See the Adding Actions and Hooking Them Up in the UI chapter on page
12-1 for information on how to create actions.
• The Windchill framework for creating wizards and processing wizard data.
base type A hard or soft type class that is the root type of the wizard's type picker. If the wiz-
ard does not have a type picker, this is the type of object that will be created. The
base type is used to look up the correct JSPs for wizard steps that have different jsp
variants for different subtypes until a specific type is selected by the user.
context The container (Product, Library, Project, etc.) in which you are creating the
object(s).
dependent attribute An attribute whose value and/or display characteristics are wholly or
partially determined by the value of another attribute (called the "driver
attribute") via an object initialization rule (OIR), access control policy, or
other mechanism.
driver attribute An attribute whose value drives the value and/or display characteristics of
another attribute (called a "dependent" attribute) via an object initialization
rule (OIR), access control policy, or other mechanism.
hard type An object type defined in a Java class. Hard types are typically modeled
using Rational Rose and may extend out-of-the-box Windchill business
object classes.
object type A Java class or soft type defining the attributes and behavior of the business
object(s) you want to create.
soft attribute An attribute of the object defined in the Windchill Type and Attribute
Manager client. These attributes are not defined in the Java business object
class and are stored in database tables separate from the table for the business
class.
soft type An object type defined using the Type and Attribute Manager rather than in
a Java class. Soft types may extend other soft types but all have a hard type
as their root type.
Solution Elements
Element Type Description
Tags
All the tags below are defined in the <WT_HOME>/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.
Tag handler:
com/ptc/core/components/tags/co
mponents/DescribePropertyPanel
Tag
JSPs
The following jsp and jspf files can be used to create and display components common to many create wizards.
Unless otherwise noted, they are located in the <WT_HOME>/codebase/netmarkets/jsp/object and
<WT_HOME>/codebase/netmarkets/jsp/components directories.
Beans
CreateAndEditWizBean Java class; Runs in the servlet This bean is available to your jsps
engine and the Method Server if you include the includeWizBean
jspf file. It has getter methods for
wizard data set by the
initializeItem tag such as the
operation, default container, the
base type, and so forth.
Javascript
Java Classes
You can use the classes below to help create and process your wizard. They are located in the
<WT_HOME>/codebase/WEB-INF/lib/wncWeb.jar file.
ContextWizardStepValidator Java class; runs in the Method A class that may be called to
Server validate the data in the Set Context
wizard step.
DefineObjectStepValidator Java class; runs in the Method A class that may be called to
Server validate the data in the Define
Object wizard step.
SetAttributesStepValidator Java class; runs in the Method A class that may be called to
Server validate the data in the Set
Attributes wizard step.
ObjectBean Java class; runs in the Method A container for the form data
Server specific to one target object and for
the data common to all objects.
Provides methods to retrieve the
form data for the associated object.
A wizard creating only one object
will have only one ObjectBean.
FormResult Java class; runs in the Method A class used to pass method results
Server and client between server processor methods
and from the server to the
WizardServlet.
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.
This document will refer to attributes whose values affect the values of other
attributes as “driver attributes.” The affected attributes will be called “dependent”
attributes. Driver attribute values must be determined “upstream” of any attribute
– Context panel
Read-only information about the object being created that is derived from
the launch context or entered on previous wizard steps. If the object is
WTContained this typically displays the container for the new object
– Type picker
The base type for the wizard is derived from an attribute on the
InitializeItem tag or, if none, from the object type associated with the
wizard action. (More about the InitializeItem tag later.) If you want to
allow users to create either the base type or a subtype of the base type you
would include a type picker in your wizard.
The list of types available in the type picker is typically determined as
follows:
1. Compute the list of hard and soft subtypes of the base type. Soft
subtypes are the instantiable soft types defined for the base type
in the given organization container.
4. Based on the default initial life cycle state and the the
administrative domain of the folder location, determine whether
the user has create permission for each type. If not, filter that
type from the list.
The default value for the type picker is determined from a preference for some
base types, as follows:
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.
When objects are being created from a template, such as creating a document
from a template, the type picker is replaced by a template picker and the type
of the new object is determined from the template.
– Driver attributes
This property panel displays input fields for attributes that can drive the
values of and/or constraints on other attributes to be entered by the user.
If a value in this panel is changed, all subsequent wizard steps are
automatically refreshed based on the new attribute value(s). Therefore it
is important to place all driver attributes in this section.
If the preference Display -> Expose Organization is set to true and the
object is OrganizationOwned, this panel should include a picker for the
organization attribute of the object. Although organization id does not
drive the value of other attributes out-of-the-box, customers often want to
set up such dependencies.
The object type indicates which other attributes should be included, if
any.
3. Set Attributes step
This step is where information for most non-driver attributes for the object is
gathered. It generally consists of two to four parts, which may include the
following: a read-only context property panel, primary content input fields
(for FormatContentHolder objects only), an attribute input table, and
– Context panel
Read-only information about the object being created that is derived from
the launch context or data entered on previous wizard steps. This will
usually contain the object type. If the new object is WTContained it will
also display the container name. If the new object is OrganizationOwned
and the preference Display -> Expose Organization is set to true it will
also display the organization id.
– Primary content
Wizards to create objects that are FormatContentHolders, such as
WTDocuments, should have a section for the user to enter the primary
content item. .
– Attribute input table
4. Additional steps
Your wizard may contain additional steps pertinent to the type of object being
created.
Steps for which common components are available are:
– Classification attributes step
This step only applies to WTParts and subtypes thereof when PartsLink is
installed. It is a dynamic step that only appears if the part is classified. It
allows the user to modify the classification attributes of the part. It
displays the classification of the part in view mode at the top and then
– Attachments step
This step is typically included when creating objects that are
ContentHolders. It allows the user to attach documents, links, and other
content to the new object. See the Attachments section in the
Customizing HTML Clients Using the Windchill JSP Framework chapter
on page 11-16 for information on incorporating this step.
Some object types may require additional steps to capture other information
needed to create the object. No jsp files are provided for such unique wizard
steps. However, you can develop your own jsp files for unique steps using the
same table, property panel, and javascript components used in the jsp files for
common steps.
By default, the name attribute of the action points to the main jsp page for your
wizard relative to codebase/netmarkets/jsp, unless a url attribute is specified on
the command tag. Therefore, for the action above, the system would expect to
find a jsp file named <WT_HOME>/codebase/netmarkets/jsp/<objecttype
name>/<your wizard action name> to use for the main page of your wizard.
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:
The command class is the java class that should be called to process the wizard
data. Typically, this will extend CreateObjectFormProcessor. See Creating Your
Form Processor and Form Processor Delegates section on page 15-75 for more
information.
Note that it is not necessary to specify a “method” attribute in the command tag if
your form processor class extends DefaultObjectFormProcessor or
CreateObjectFormProcessor.
Here is an example action for launching a creation wizard for “MyPart” objects:
<objecttype name="myPart" class="ext.part.MyPart"
Step Object Type Action definition / File location / Associated JSP page
name yes None any string The name of the action. Used as the “name”
attribute on wizard step tags.
required no false “true” or Specifies whether the user must navigate to the step
“false” or not. The Finish button will not be enabled until
the user has completed all required steps.
beforeJS no None any string Specifies the name of a javascript function to call
when the wizard step is loaded
afterJS None any string Specifies the name of a javascript function to call
when the user clicks Next or OK on the wizard
step. Can be used to do client-side validation of the
form data.
beforeVK no None any string The name of a validator key specifying a Method
Server validator to be called when the user
navigates to the step using the Previous or Next
button.
afterVK no None any string The name of a validator key specifying a Method
Server validator to be called after the user clicks
Next or Finish on the step. Can be used to do
server-side validation of the form data.
Note that the “windowType” attribute of the command subtag should always be
set to “wizard_step.”
Creating service.properties Entries for the Define Object and Set Attributes Steps
You will notice that the command tag for both the Define Object and Set
Attributes wizard step actions above contain a url attribute referencing the
TypeBasedIncludeServlet. The TypeBasedIncludeServlet allows the system to
look up the correct jsp page to use for a wizard step or part of a wizard step on-
the-fly given an action name and the type of object to be created. Using this
servlet for the url for wizard steps allows:
• wizards for different object types to share the same step action definition
• reuse of the same wizard action and main wizard jsp for different object types
if the wizards are identical except for steps that use the
TypeBasedIncludeServlet for jsp lookup. Typically this is most useful when
you want to use the same wizard to create different subtypes of a base type.
For the Define Object step a default jsp is available, but you can override this by
use of the TypeBasedIncludeServlet and still use the common action definition for
your step. For the Set Attributes step, use of the TypeBasedIncludeServlet allows
you to specify different step jsps for the different object types that might be
selected by the user in the Define Object step without creating a new action for the
step or a new wizard.
The TypeBasedIncludeServlet looks up the correct jsp using
ApplicationContextServices and service.properties files. It locates the file entry
for the service “com.ptc.netmarkets.util.misc.FilePathFactory” that has a selector
matching the contextAction parameter on the url in the action tag and a requestor
object type matching the type of object the user has chosen to create. The value of
that entry gives the path of the jsp page for the step, relative to
<WT_HOME>/codebase. Entries are formatted as follows:
Xconf file:
wt.services.applicationcontext.TypeBasedServiceProviderFromProp
erties.customPropertyFiles
See the Adding a Custom Service Provider Property File section on page 5-27 for
more information on service property files.
Most wizard steps will also use tags in the components.tld tag library and so will
also need to include that as follows:
<%@ taglib prefix="jca"
uri="http://www.ptc.com/windchill/taglib/components"%>
JSP Description
How to modify the contents of the read-only property panel in the step
1. Create a new main jsp file for the step.
2. Copy the contents of the file
<WT_HOME>/netmarkets/jsp/object/defineItemWizStep.jsp into your new
main jsp file.
Attribute Value
var “defineItemStepContextPanelDescriptor”
id “defineItemStepContextPanelDescriptor”
scope “request”
mode “VIEW”
Alternatively, you could include a new jspf file that contains your
describePropertyPanel tag instead of placing it in-line. See the Sample
Code section on page 15-84 for an example.
Attribute Value
var “attributesTableDescriptor”
id “attributesTableDescriptor”
(recommended, not required)
scope “request”
You can make use of the Property Report described in the section Attribute
Input Tables and Panels earlier in this section to obtain the ids for the
attributes you want to include in your table. Also, refer to theAttribute
Handling section on page 14-2 and the Soft Attributes and SCAs section on
page 14-21 of the Presenting Information in the UI chapter for a description of
some server calculated attributes (SCAs) that you might want to include.
If your object is a subtype of WTPart and you want to include a classification
picker in your table, you would add the following property to your table:
<jca:describeProperty id="classification.id"
label="${classificationLabel}"/>
and you must include the following hidden fields in the page:
<input id="selectedClfNodes" type="hidden"
name="selectedClfNodes" >
Attribute Value
var “attributesStepReadOnlyPanel”
id “attributesStepReadOnlyPanel”
(recommended, not required)
scope “request”
The ContextWizardStepValidator just validates that the form data contains a valid
container object reference.
The DefineObjectStepValidator and SetAttributesStepValidators look at all the
form data with the special name attribute described in the Creating Your Step JSP
Pages section on page 15-63, Attribute Input Tables and Panels. They validate the
data against all constraints that were defined for the attributes in the Rose model
or Type Manager. They do that by calling the preProcess() method of the
InitializeItemTag
The InitializeItem tag initializes some data for the object being created from the
launch context of the wizard and the attributes passed to the tag. This
information includes:
• type of operation (create or edit)
• the base type of the object being created
• default container
• initial value for the type picker
• type instance identifier for the object being created
Wizard tag
This tag has wizardStep subtags describing the steps of the wizard. The action
parameter of these subtags points to the action defined for the step. If you are
using the predefined action definition for a step, be sure the action parameter
matches the name parameter of the action See Creating actions and/or service
property entries for your wizard steps on page 15-60 for more information.
The wizard tag also defines the buttons to be used Typically, wizards will use one
of the two following button sets defined in codebase/actionmodels.xml:
• DefaultWizardButtonsNoApply (for multi-step wizards)
• NoStepsWizardButtons (for single-step wizards)
However, other buttons sets are available in actions.xml and custom button sets
can be defined.
The wizard tag has an optional formProcessorController attribute. This should
not be needed for single-object create wizards.
See the Windchill Client Architecture Wizard section on page 15-2 for more
information on the wizard tag.
WTChangeIssue com.ptc.windchill.enterprise.change2.forms.processors.C
reateProblemReportFormProcessor
WTChangeRequest2 com.ptc.windchill.enterprise.change2.forms.processors.C
reateChangeRequestFormProcessor
WTChangeOrder2 com.ptc.windchill.enterprise.change2.forms.processors.C
reateChangeNoticeFormProcessor
WTChangeActivity2 com.ptc.windchill.enterprise.change2.forms.processors.C
reateChangeTaskFormProcessor
WTVariance com.ptc.windchill.enterprise.change2.forms.processors.C
reateVarianceFormProcessor.
If the behavior of 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 it does not
meet your needs, you should write a subclass of it to process the wizard form data.
Note that you do not need to create your own processor if you only want to
provide special code for setting an attribute. In that case, you need only to write a
FormProcessorDelegate to handle this task. Remember to register the
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.
try
{
< persist the object >
}
catch(WTException e)
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.
Case 4: You need to set attributes on the new object programmatically
You may have attributes that you need to set on the object before it is persisted
which are not exposed in the UI.
Solution: There are alternate ways to handle this.
• Create a FormProcessorDelegate and implement its preProcess() method. In
that method, set the attribute values on the object in the ObjectBean. Add a
hidden form field to your wizard jsp specifying the name of your delegate,
which will be automatically instantiated by the framework. For example:
<input type="hidden" name="
${createBean.formProcessorDelegateConstant}" value=" <path name
of your delegate> ">
if (!continueProcessing(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.
Customization Points
baseTypeName the type any Windchill type No The string form of the Windchill type
associated with identifier string identifier for the class of object to
the wizard create. For example,
action "wt.part.WTPart" or
"wt.part.WTPart|MySoftPart".
This class will be the root type in the
wizard's type picker. It is also used to
look up the correct jsps for wizard
steps that have different variants for
different subclasses until a specific
type is selected in the type picker.
Optional. If not specified,
the type associated with the wizard
action will be used.
Possible
Parameter Default Value Value Req? Description
seedType None any Windchill No The top-level type that should be used to
type identifier generate the list of types. For example,
string (logical or "wt.part.WTPart". May include more
external) than one of these parameters.
defaultType For certain any Windchill No The type that should be selected by
types the default type identifier default. For example, "wt.part.WTPart."
is taken from a string (logical or May be a string, such as "Select a Type"
preference (see external) rather than a type name.
Background on
page 15-38) For
all other
wizards, the
base type is
used.
filterType None any Windchill No A type that should be excluded from the
type identifier type list. For example, "SoftPartType1".
string (logical or The descendants of the filter type are also
external) excluded. May include more than one of
these parameters.
displayHierarch false true (to display No Indicates whether the type list should be
y hierarchy) displayed as a flat list or in hierarchical
form.
false (to display
flat list)
showRoot true true (to display Whether the seedTypes should not be
seed types) displayed.
false (to not
display seed
types)
Sample Code
<%@ include
file="/netmarkets/jsp/components/defineItemReadOnlyPropertyPanel.j
spf"%>
<jca:configureTypePicker/>
JSP for the Define Object Step of the New Part Wizard
Filename: <WT_HOME>/codebase/netmarkets/jsp/part/defineItemWizStep.jsp
<jca:describePropertyPanel
var="defineItemStepContextPanelDescriptor"
id="defineItemStepContextPanelDescriptor"
scope="request" mode="VIEW" type="wt.part.WTPart">
<jca:describeProperty id="containerName"
label="${createBean.containerLabel}"/>
</jca:describePropertyPanel>
<%-- 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>
</jca:configureTypePicker>
</c:when>
<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>
JSP for the Set Attributes step of the New Problem Report Wizard
Filename:
<WT_HOME>/codebase/netmarkets/jsp/problemReport/create_details.jsp
Elements typical to most Set Attributes step jsps are shown in bold.
<%@taglib uri="http://www.ptc.com/windchill/taglib/components"
prefix="jca"
%><%@taglib uri="http://www.ptc.com/windchill/taglib/fmt"
prefix="fmt"
%><%@taglib
uri="http://www.ptc.com/windchill/taglib/changeWizards"
prefix="cwiz"
%><%@include file="/netmarkets/jsp/components/beginWizard.jspf"
%><%@include
file="/netmarkets/jsp/components/createEditUIText.jspf"
<%@ include
file="/netmarkets/jsp/change/setAttributesReadOnlyPropertyPanel.js
pf"%>
<cwiz:initializeSubmitNow/>
<%@include
file="/netmarkets/jsp/components/setAttributesWizStep.jspf"%>
<script language='Javascript'>
loadAllRemainingNonRequiredSteps();
</script>
<%@include file="/netmarkets/jsp/util/end.jspf"%>
<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" />
</jca:wizard>
%@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>
Objective
You need to develop a wizard to allow a user to edit the attributes of a Windchill
business object and update the object in the database.
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
Rose model or Attribute and Type Manager.
• 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.
Prerequisite knowledge
To achieve this objective, you need to be familiar with the Building Wizards to
Create a Single Object topic (see page 15-38 for more information), especially the
Prerequisite knowledge section is on page 15-43.
Tags
autoCheckOutItem Tag Checks out the object to the current user if it is not
already checked out. Adds an object reference to
Note: All of the tags in the
the working copy as an attribute of the current
Solution Elements section of the
HTTPRequest, as a parameter in
Building Wizards to Create a
HTTPRequestData parameter map of the
Single Object topic are also
NmCommandBean, and as a hidden field in the
applicable to edit wizards. This tag
DOM. The key to the working copy value is
is in addition to those.
CreateAndEditWizBean.WORKING_COPY_RE
See Building Wizards to Create a F_PARAMETER_NAME.
Single Object on page 15-38 for
This tag should be put in the main JSP for the
more information. (The Solution
wizard immediately below the initializeItem tag.
Elements section is on page
15-43.) Tag library: <WT_HOME>/codebase/WEB-
INF/tlds/workinprogress.tld
Tag handler:
com.ptc.windchill.enterprise.wip.tags.AutoCheck
OutObjectTag
JSPs
setAttributesWizStep jspf file A jsp file (also used for create wizards) that can be
included in the jsp for your Set Attributes wizard
step. This will get the model data for and render
your attributes panel and table if you have named
them per the instructions in this document.
Runtime location:
<WT_HOME>/codebase/netmarkets/jsp/compon
ents
setAttributesWizStepWithContent jspf file A jsp file that can be included in the jsp for your
.jspf Set Attributes wizard step if your object type is a
FormatContentHolder. It does the same things as
the jsp above but, in addition, will render input
fields for capturing primary content.
Location:
<WT_HOME>/codebase/netmarkets/jsp/docume
nt
Beans
CreateAndEditWizBean Java class; Runs in This bean is available to your jsps if you include
the servlet engine the includeWizBean jspf file. It has getter
and the Method methods for wizard data such as the operation
Server (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
<WT_HOME>/codebase/WEB-
INF/lib/wncWeb.jar file.
CreateAndEditModelGetter Java class A class that may be called via a getModel tag to
generate the data for property panels and attributes
Runs in the Method
tables in edit wizards.
Server
EditAttributesStepValidator Java class; runs in A class that may be called to validate the data in
the Method Server the Set Attributes wizard step.
– Context panel
Read-only information about the object being edited. This varies by
object type. Typically, the object type is displayed. If the object is
WTContained it also usually displays the container name. If the new
object is OrganizationOwned and the preference Display -> Expose
Organization is set to true it also typically displays the organization id.
Creating Actions and/or Service Property Entries for Your Wizard Steps
You may be able to use out-of-the-box action definitions for wizard steps that are
common to multiple wizards. The following wizard step actions are defined out-
of-the-box.
Note that the selector string matches the contextAction parameter on the URL in
the step action.
For example, to use the jsp page
<WT_HOME>/codebase/netmarkets/jsp/ext/part/myPart/setAttributesWizStep.js
p for the Set Attributes step when editing objects of type ext.part.MyPart you
would add the following entry to a type-based service.properties xconf file:
<Resource context="default"
name="com.ptc.netmarkets.util.misc.FilePathFactory">
<Option requestor="ext.part.MyPart"
resource=
“/netmarkets/jsp/ext/myPart/setAttributesWizStep.jsp”
selector="editAttributesWizStep"/>
</Resource>
Attribute Value
var “attributesStepReadOnlyPanel”
id “attributesStepReadOnlyPanel”
(recommended, not required)
scope “request”
2. A describeAttributesTable tag for editing hard and soft attributes. The mode
of this tag should be set to “EDIT.” (See the section Attribute Input Tables
and Panels above for how to make individual attributes view-only.) You
should also set the following tag attributes if you want to use the out-of-the-
box jspf file described in the next step for getting the table model and
rendering the table.
Attribute Value
var “attributesTableDescriptor”
id “attributesTableDescriptor” (recommended,
not required)
scope “request”
and you must include the following hidden fields in the page:
<input id="selectedClfNodes" type="hidden"
name="selectedClfNodes" >
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/>
InitializeItemTag
Like create wizards, edit wizards require an initializeItem tag. Instead of setting
the operation attribute of this tag to ${createBean.create}, you should set it to
${createBean.edit}. The following tag attributes are not applicable to edit
wizards: objectHandle, baseTypeName.
Wizard Tag
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
<WT_HOME>/codebase/config/actions/actionmodels.xml.
To include a Set Attributes step in your wizard you should provide a wizardStep
tag with the action name “editAttributesWizStep” (if you are using the common
step action shown in the Creating Actions and/or Service Property Entries for
Your Wizard Steps section on page 15-97) or the action name you specified on
your custom action.
To include Set Classification Attributes and/or Attachments steps, use the action
names shown for these steps in Creating Actions and/or Service Property Entries
for Your Wizard Steps section on page 15-97).
<script language="Javascript">
</script>
<script language="Javascript">
</script>
com.ptc.core.components.forms.EditWorkableFormProcessor- for
Workable objects
WTChangeIssue com.ptc.windchill.enterprise.change2.forms.process
ors.EditProblemReportFormProcessor
WTChangeRequest2 com.ptc.windchill.enterprise.change2.forms.process
ors.EditChangeRequestFormProcessor
WTChangeOrder2 com.ptc.windchill.enterprise.change2.forms.process
ors.EditChangeNoticeFormProcessor
WTChangeActivity2 com.ptc.windchill.enterprise.change2.forms.process
ors.EditChangeTaskFormProcessor
WTVariance com.ptc.windchill.enterprise.change2.forms.process
ors.EditVarianceFormProcessor
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 the
Creating Your Form Processor and Form Processor Delegates section on page
15-75 for examples of cases where you may need to implement your own
processor.netmarkets/jsp/components/beginWizard.jspf
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.
Sample Code
JSP for the Set Attributes Step of the Edit Part Wizard
Filename:
<WT_HOME>/codebase/netmarkets/jsp/part/editPartAttributesWizStep.jsp
<%@ taglib uri="http://www.ptc.com/windchill/taglib/components"
prefix="jca"%>
<%@ taglib tagdir="/WEB-INF/tags" prefix="tags"%>
<jca:describeProperty id="containerName"
label="${createBean.containerLabel}"/>
<jca:describeProperty id="partTypeName"
label="${typeNameLabel}"/>
<jca:describeProperty id="orgid" need="organization.id"/>
</jca:describePropertyPanel>
<%-->
Source uses a special data utility to hide the other options
except 'Buy' if SUMA is installed and the part type is
manufacturing or vendor
<--%>
<jca:describeProperty id="source"/>
<%-->
The following 3 are WADM specific attributes. They are hidden by
the PartSolutionGroup logic if WADM is not installed.
<--%>
<jca:describeProperty
id="<%=PartConstants.ColumnIdentifiers.WADM_CONTRACT_NUMBER%>"/
>
<jca:describeProperty id="classification.id"
label="${classificationLabel}"/>
<jca:describeProperty id="minimumRequired"
label="${minimumRequiredLabel}"/>
<jca:describeProperty id="maximumAllowed"
label="${maximumAllowedLabel}"/>
<jca:describeProperty
id="ALL_CUSTOM_HARD_ATTRIBUTES_FOR_INPUT_TYPE"/>
<jca:describeProperty
id="ALL_SOFT_NON_CLASSIFICATION_SCHEMA_ATTRIBUTES"/>
</jca:describeAttributesTable>
<%@ include
file="/netmarkets/jsp/components/setAttributesWizStep.jspf"%>
<%@ include file="/netmarkets/jsp/util/end.jspf"%>
<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>
%@include file="/netmarkets/jsp/util/end.jspf"%
<%-->
PartHelper.js contains the “onloadEditPartWizard” method
<--%>
<% 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
<--%>
<jca:wizardStep action="editAttributesWizStep"
label="${editAttributesWizStepLabel}" type="object"/>
<jca:wizardStep action="setClassificationAttributesWizStep"
type="part"/>
<%-->
<--%>
<jca:wizardStep action="attachments_step"
label="${attachmentsWizStepLabel}" type="attachments" />
</jca:wizard>
<%@include file="/netmarkets/jsp/util/end.jspf"%>
Topic Page
Information Pages..............................................................................................16-2
16-1
Information Pages
Objective
You want to create an object information page specific to a given business object.
Solution
Use the Info Page Common Component with an info.jsp file associated to that
object type.
Design Overview
There are many types of business objects in Windchill, plus potentially many soft
types or modeled object types introduced by customers. Each type of object can
potentially have its own associated information page, a page that displays
information around a selected instance of that type. While the information
associated with different object types can vary widely, it is important to maintain
a common look and feel among the multitude of information pages. The info page
component was developed to give the Windchill products consistency for
displaying an object details page. The component is also intended to make
developing an info page much easier. Using the component, a developer only
needs to configure certain parts of the page (list of actions, which attributes to
show, etc.) while the main layout of the page is provided by the component.
Applicability
This documentation should be used for configuring the info page for some
business object in one of the Windchill products.
Design Elements
The info page component
• Page title area
• Top attributes panel
• Visualization area
• Navigation menu
• Filter area
• Content area
• Global navigation
• Type-specific data
Collaborations
• The info page component controls the layout of the various other components
on the page; page title area, top attributes panel, visualization area, navigation
menu, filter area, and content area, as well as including the global navigation.
• The info page component supports type based lookups (including soft types)
for the type specific data, attributes, 3rd level navigation menu.
• The info page component hooks up to the global navigation as appropriate
(e.g.: tab highlighting)
• The info page component displays the correct action list based on object type
• The info page component registers the object in the recently visited list
• The info page component registers the user and the object in the auditing
service for the view event
• The info page component does role based checking on attributes
• The info page component allows Status Glyph Indicators
Consequences
By following this documentation the configuration of all objects info pages should
be done in a consistent manner. This will make maintaining these info pages a
much easier and more manageable task and have a consistent user model.
Implementation
Overview
The info page component was developed using the Windchill client architecture.
This component provides a common layout for an object’s information page as it
is displayed in any of the Windchill products. Using the info page component will
provide consistency between all objects and Windchill products. The specific
content that is displayed for any given object type will be configured by
overriding certain elements in the context of the specific object types.
Configurable portions of the page include things like which action list is used and
which attributes are shown in the top attribute panel.
Create a jsp
Your info page jsp will have a describeInfoPage tag, a describePropertyPanel tag,
and an include of the info page component, infoPage.jspf. Based on the
configuration in the describeInfoPage and describePropertyPanel tags, the
infoPage.jspf component will render the object icon, object identification, status
glyphs, help link, action list, attributes panel (property panel), visualization
component, 3rd level navigation and 3rd level navigation content.
Before the include of infoPage.jspf, your jsp can set up what information is
displayed on the page. (e.g. what attributes to show, whether or not visualization
applies, what action model to use for 3rd level nav etc.) See section 9.4 for the
properties that can be configured in your info page jsp:
For example:
<jca:describePropertyPanel var="propertyPanelDescriptor">
<jca:describeProperty id="name" />
<jca:describeProperty id="number" />
</jca:describePropertyPanel>
<jca:describeInfoPage showVisualization="true"
helpContext="part_details_help"
navBarName="third_level_nav_part"
propertyPanel="${propertyPanelDescriptor}">
<jca:describeStatusGlyph id="statusFamily_Share" />
<jca:describeStatusGlyph id="statusFamily_General" />
<jca:describeStatusGlyph id="statusFamily_Change" />
</jca:describeInfoPage>
<Resource context="default"
name="com.ptc.netmarkets.util.misc.FilePathFactory">
<Option requestor="<fully qualified class path>"
resource="<jsp path relative to codebase>"
selector="InfoPage"/>
</Resource>
See the About the xconfmanager Utility section in the Windchill Utilities chapter
on page 6-2 for more information.
<jca:describeInfoPage propertyPanel="${propertyPanelDescriptor}">
…
</comp:describeInfoPage>
To determine the set of available properties that can be displayed for an object
type, you can use the property report.
To specify which actionmodel to use as the actions list for a specific class or
softtype, use the attribute menufor as specified in the following example:
<!-- Part information page Actions list -->
<model name="more parts actions" menufor="wt.part.WTPart">
<action name="view" type="object"/>
<action name="viewDefaultRepresentationPV" type="wvs"/>
<action name="viewDefaultRepresentationPVLite" type="wvs"/>
<action name="launchPSE" type="explorer" />
<action name="launchABE" type="explorer" />
<action name="separator" type="separator"/>
<action name="checkin" type="wip"/>
<action name="checkout" type="wip"/>
<action name="undocheckout" type="object"/>
…..
For example:
<!-- your comment here -->
<model name="<your_action_model_name>" menufor="<fully qualified
classpath>">
<action name="view" type="object"/>
</model>
Or, if you want to have multiple classes or soft types you can comma separate the
list:
The info page uses what is registered in actionmodels.xml with menufor as the
action list. You can override what is registered in actionmodels.xml by
configuring the describeInfoPage with a different actionListName to use:
<jca:describeInfoPage actionListName="<action model name>" >
…
</jca:describeInfoPage>
For example:
<Resource context="default" name="wt.help.HelpTemplate">
Selector is a help selector key that will be set on the describeInfoPage tag. In the
above example it is PMPartStructureEdit_help.
Resource is the help file location and is assumed to be an html file. The help file
gets a base of $WT_HOME/codebase/wt/helpfiles/help_<locale>
Hence in the above example where
resource="online.pdm_prodmgmt.PMPartStructureEdit" the english help file will
be:
$WT_HOME/codebase/wt/helpfiles/help_en/online/pdm_prodmgmt/PMPartS
tructureEdit.html
Requestor is the class of the container context that the object is in. For example,
parts could be created in either Products or Projects. If the help topic for parts in
Projects had to be different from the help topic for parts in Products, an entry
could be added with requestor="wt.projmgmt.admin.Project2".
Once the above xconf entry is created, the help topic can be set on the info page
by adding the selector on the describeInfoPage tag:
<jca:describeInfoPage helpContext="<help selector key>" >
…
</jca:describeInfoPage>
Configure the Third Level Navigation Menus for your object type
The following is an example configuration of a third level navigation menu for the
part info page:
<!-- Part information page 3rd level nav menu bar -->
<model name="third_level_nav_part">
<action name="productStructure" type="object"/> <!-- Structure -->
<submodel name="general"/> <!-- General -->
As you can see it is a combination of an action and submodels. An action in the 3rd level
nav bar will be displayed as just a link. (e.g. Product Structure browser) A submodel in the
3rd level nav bar will be displayed as a drop down menu (e.g. Related Items menu)
The General, Related Items, History and Collaboration menus are meant to be reused for
all object types. Actions that do not apply for certain object types will be removed via
action validation. So your action model would probably look something like this:
<!-- your comment here -->
<model name="<your_action_model_name>">
<submodel name="general"/> <!-- General -->
<submodel name="relatedItems"/> <!-- Related Objects -->
<submodel name="history"/> <!-- History -->
<submodel name="collaboration"/> <!-- Collaboration -->
</model>
Then the image below would be the resulting 3rd level nav content (the action that
led to the above jsp was added to the relatedItems submodel so that is why
“Related Objects” is highlighted)
Default Possible
Parameter Value Values Req? Description
Sample Code
2. Register your jsp so the info page servlet will know to forward to it.
Add the following entry into codebase/typedservices.properties:
wt.services/rsc/default/com.ptc.netmarkets.util.misc.FilePathFa
ctory/InfoPage/wt.part.CoolPart/0=/netmarkets/jsp/coolpart/info
.jsp
3. Test your new jsp. The icons from the Home page or from the Folders page
should lead to the new info page servlet. The URL will look something like
this:
http://<machine>/<WindchillAppName>/servlet/TypeBasedIncludeSer
vlet?oid=OR:wt.part.CoolPart:62028
5. Then, you’ll need to describe a property panel that contains the attributes that
apply for your object type. Using the property report on your build (see
Property Report on page 15-64), find the attribute names you want to use:
<jca:describePropertyPanel var="propertyPanelDescriptor">
<jca:describeProperty id="name" />
<jca:describeProperty id="number" />
</jca:describePropertyPanel>
6. Next, describe the info page. Specify the third level nav, the help file, whether
visualization applies, which property panel to use, and the status glyph
families to be shown:
<jca:describeInfoPage showVisualization="true"
helpContext="<cool_part_info_help>"
navBarName="<third_level_nav_for_cool_part>"
propertyPanel="${propertyPanelDescriptor}">
<jca:describeStatusGlyph id="statusFamily_Share" />
<jca:describeStatusGlyph id="statusFamily_General" />
</jca:describeInfoPage>
<jca:describePropertyPanel var="propertyPanelDescriptor">
<jca:describeProperty id="name" />
<jca:describeProperty id="number" />
</jca:describePropertyPanel>
Or include the line, but with the navBarName value as an empty string:
<jca:describeInfoPage navBarName="" >
…
</jca:describeInfoPage>
Known Uses
Many out-of-the-box business objects in Windchill have info pages that are built
using the Info Page component. Here are a couple examples:
• WTPart – codebase/netmarkets/jsp/part/info.jsp
• WTDocument – codebase/netmarkets/jsp/document/info.jsp
Topic Page
Picker Interaction ............................................................................................. 17-2
Common Picker Configuration Options......................................................... 17-14
Configuring a Context Picker......................................................................... 17-18
Configuring an Item Picker ............................................................................ 17-24
Configuring an Organization Picker............................................................... 17-31
Configuring a Type Picker ............................................................................. 17-37
Configuring a User Picker.............................................................................. 17-50
Configuring a Participant Picker .................................................................... 17-57
17-1
Picker Interaction
Objective
You want to configure a property picker in some wizard step and manage
interaction between that page and the picker.
Background
There are many types of business objects in Windchill, plus potentially many soft
types or modeled object types introduced by the user. These types would
predominantly would have some relationship with the other types. There are
numerous instances when user creates or updates objects of such types using an
user interface, he would need to specify the property value(s) derived from the
other available objects of the same or different type. e.g. The business object like
Part or Document are owned by a specific organization and hence at the time of
their creation user needs to be able to specify an owning organization.
This sort of user interaction is achieved through the use of property picker. The
property picker simply aids in picking up a property from an existing business
object. The user would pick an object by launching the picker and have it’s pro
properties used to update visible and/or non-visible properties on the page. The
following sketch illustrates this sort of interaction pictorially.
Scope/Applicability/Assumptions
Assume you have a customized type <myObjectType> object needing to be
created. On the first step of the create wizard, you need to define a relation ship
with an object of type <someObjectType>. This spawns a need to let user select
the object he desires from a picker and have the attributes of these objects used to
populate some content on the first step of the create wizard.
Solution
Follow the design concept as described to facilitate the picker interaction.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving HTML forms, JSP, JavaScript based DOM
manipulations, AJAX
• The actions framework in the Windchill client architecture
• The table component to list the objects.
• The wizard component in the Windchill client architecture
create_step_<step no>.jsp JSP This JSP page provides the content for the specified
step of the Create Wizard . This step would include
the controls to launch a picker and populate values
from the picked object.
This JSP could as well render a javascript picker
callback function to be executed once the picker ‘OK’
action is executed.
Run time Location:
<Windchill>\codebase\netmarkets\
<myObjectType>\create_step_<stepno>.jsp
<someObjectType>_picker.jsp JSP This JSP page defines a single step wizard with ‘OK’
and ‘Cancel’ actions for the wizard. The wizard step
would render a content that presents a list of
<someObject> in table or tree component. The user
would select the object of interest by ticking the check
boxes to select row(s) in the table.
Run time Location:
<Windchill>\codebase\netmarkets\<
someObjectType >\
<someObjectType>_picker.jsp
<someObjectType>_picker_st JSP This JSP page defines the content for the picker
ep.jsp wizard step. This step can contain a table listing the
objects of <someObjectType> or search criteria along
with
Run time Location:
<Windchill>\ codebase\netmarkets\<
someObjectType >\
<someObjectType>_picker_step.jsp
Actions.xml XML The file has definitions of all the actions. The action
that launches picker need to get defined for the type
<myObjectType>. The picker wizard step actions as
well get defined in this file.
The ‘picker.jspf’ is needed to be included in the picker page always. It defines the
following javascript window variables to track the pickerCallback and
jcaPickerCallback functions. These windows variables are needed to be used in
the ‘OK’ action javascript user submit function .
The ‘setUserSubmitFunction’ is needed to be invoked to configure wizard ‘OK’
action to invoke a javascript function.
The javascript callback definition would be as well included in this page, the
definition of this callback and any other definitions of functions the callback calls
need to be placed preferably before the ‘end.jspf’ is included.
Use a picker
To use the existing picker, the user would have to perform the following
procedures.
Define the action to launch a picker
<action name="launch<SomeObjectType>Picker">
<command windowType="popup"/>
</action>
</objecttype>
tab_tbox.setId("<SomeObjectType>Name_tbox_id");
tab_tbox.setName("<SomeObjectType>Name_tbox_id");
%>
Create the non-visible input fields that would be as well updated as a part of the
picker interaction in the client page mentioned above.
<input id="<SomeObjectType>Reference" type="hidden" value=" " />
</p:propertyPicker>
The above usage supposes that user would be interested in using the ‘name’ and
‘oid’ attributes from the information extracted for the pickedObject.
c=com","class":"wt.org.WTUser","name":"Administrator"},{"oid":"uid
=demo,ou=peopl
e,cn=koakx10-
44,dc=ptcnet,dc=ptc,dc=com","class":"wt.org.WTUser","name":"demo"}
]
Default
Parameter value Possible values Required? Description
label Any String Value Yes The localized display label of the
property the value of which is to
be populated using a picker.
name Any String value Yes The name of the action as it exists
in ‘actions.xml’
type Any String value Yes The ‘type’ of the action for which
the definition exists in
‘actions.xml’ that would launch
the picker.
Possible
Parameter Default values values Required? Description
from Any String Value Yes Specifies the name of the property
(attribute) of the picked object
to Any String value Yes HTML 'id' of the form input element
but adhering to to update on the parent page.
HTML ‘id’
attribute
specification
criteria
Possible
Parameter Default values values Required? Description
value Any String Value Yes Value of the URL query string
parameter to be passed to the
popup picker.
Sample Code
User can refer to the following code which is available in the product, it is a type
picker.
codebase\WEB-INF\tags\organizationPicker.tag - Defines the organizationPicker
tag definition that uses internally the propertyPicker tag. Just a way to encapsulate
abstract design concept.
Following snippet of java scriptlet code, creates the visible and invisible form
fields to be updated using the information from the picked objects
<%…….
String displayFieldId =
id+SearchWebConstants.DISPLAY_FIELD_LABEL;
tb.setId(displayFieldId);
tb.setName(displayFieldId);
tb.setValue(defaultValue);
tb.addJsAction("readonly","readonly");
tb.setWidth(Integer.parseInt(pickerTextBoxLength));
tb.setMaxLength(Integer.parseInt(pickerTextBoxLength));
%>
The following snippet of code propagates selectively the parameters passed to the
organizationPicker tag to the propertyPicker tag
<p:propertyPicker label="${label}" field="${textbox}"
action="callSearchPicker" type="search">
<p:populate from="${displayAttribute}"
to="${displayFieldId}" />
….
</p:propertyPicker>
Following ensures that the search criteria and search results table are as well
added to the step content.
………
<TABLE>
……..
……….
……
The AJAX callback function is defined below which is actually responsible to use
the AJAX response as JSON object and populate information on the client page
using the picker callback function
function updateParent() {
…….
window.pickerCallback =
"<%=request.getParameter("pickerCallback")%>";
window.pickedAttributes =
"<%=request.getParameter("pickedAttributes")%>";
window.pickedDataFetcher =
"<%=request.getParameter("pickedDataFetcher")%>";
</script>
…..
Note: The user of the picker can as well specify his own set of callback function or
data fetcher using the pickerParam tag
<p:pickerParam name=” pickerCallback” value=”myPickerCallback” />
<p:pickerParam name=” pickedDataFetcher” value=”
jsp/components/myPickedDataFetcher.jsp” />
Following snippet ensures that all AJAX related javascript artifacts are available
for re-use.
<script type="text/javascript"
src="netmarkets/javascript/util/prototype.js"></script>
<script type="text/javascript"
src="netmarkets/javascript/components/wizard.js"></script>
codebase\netmarkets\components\picker.jspf
Objective
To configure a picker to accept seeded criteria for containers, customize it to user
specified criteria options and results.
Background
Configure a picker to only display a specific soft-type of parts (Product Areas).
Allow user to enter criteria that includes name (not number) and library. Include
criteria (that the user cannot see/edit) to retrieve libraries that are NOT in an state
of “obsolete” AND that include certain specific words in the library description.
The picker should show the product area name, not show its number, and also
include the library that contains the part.
Scope/Applicability/Assumptions
Let’s assume we need to launch a customized part picker from a JSP client which
would have the capability to define the soft type as a seed for searching and also
would respect seeded container’s to search in. We would be using our OOTB item
picker tag to launch it from a JSP page.
Intended Outcome
We should be able to launch an Item Picker which would be configured to search
in for a soft type of part. This would have a name field as criteria for the picker
where the user can filter results based on name of the part. The results table would
contain customized view for this picker where the container and the name of the
part would be shown. It would also respect seeded criteria which would filter the
query based on criteria such that the part belongs to library which has certain
words in the description and are not obsolete.
Solution
A custom JSP page would be written to launch this picker with appropriate seeded
criteria. We would be using the Item Picker tag to launch the picker.
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
Procedure – Customizing picker to have user defined criteria and result view
Launching the picker with custom component id and user defined object type
The picker can be launched by passing the above component id to customize the
search criteria as defined above.
<wctags:itemPicker id="customized_item_picker" objectType="WCTYPE|
wt.part.WTPart|org.r_and_d.mypart" componentId="
customizedItemPickerForSoftPart "/>
<Option
serviceClass="com.ptc.netmarkets.search.views.CustomizedPartVie
w" requestor="java.lang.Object" selector="
wt.part.WTPart.customizedSearchView "/>
</Service>
Sample Code
Launching the picker in <pickerlauncher>.jsp
<html>
<body>
<table>
<tr>
This is a customization where a hidden seed for container
refs is feeded to the picker.
</tr>
<tr>
<%-- launching Item Masterpicker--%>
The containerRefs passed above can be a list of comma separate container’s from
which we want to fetch the results. This parameter is optional and if not provided
would launch picker to search in all containers.
Objective
You want to pick context(s) to be used in your application.
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 Find Button along with the specified label after
using the tags for context picker. After clicking Find… button, 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 RBINFO file customizations.
• Windchill xconfmanager concepts.
pickerAttributes.xml XML file You should use this file to customize the
search criteria attributes for an object type
for your picker.
Runtime location: <WT_HOME>\codebase\
pickerAttributes.xml
searchClientResource.rbInfo RBINFO file You should use this file to localize the
contents of the pickers.
Runtime location: <WT_HOME>\src\com\
ptc\windchill\enterprise\search\client\
searchClientResource.rbInfo
contextPicker.tag Custom JSP tag file This file is contains the information about
the supported parameters for this tag.
Runtime location: <WT_HOME>\codebase\
WEB-INF\tags\itemPicker.tag
Note: You want to disable the type picker in the Context Picker.
pickedDataFetc <WebApp>/net URL location of No URL of the data fetcher file that will
her markets/jsp/sear the fetcher file be used by the AJAX call to process
ch/pickedData.js the selected results.
p.
baseWhereClaus “” (blank) Any valid I*E No Additional where clause if you want
e where clause query to filter search results on some
specific criteria regardless of user
input. This where clause will just get
“ANDed” with the internal where
clause.
searchResultsVi “”(blank) Any valid view id No This parameter allows user to define
ewId custom view id for the picker search
results table.
customAccessC “” (blank) Any valid name No This parameter is used to define your
ontroller own custom access controller. This
parameter would accept the complete
class name as the value. To specify
multiple customAccessController
you can pass on comma (,) separated
list of the class names.
excludeSubType “” (blank) Any valid subtypes No This parameter is used to exclude sub
s types from the search.
Configuring Context Picker with your own typeComponentId in the type picker
<wctags:contextPicker id="contextPickerId" typeComponentId="
Foundation.myContextPickerComponentId" />
Objective
You want to pick instance(s) of Windchill business objects.
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 Find… button, item picker will be
launched.
Solution
Use the Item Picker Common Component in your JSP file to include Item 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 RBINFO file customizations.
• Windchill xconfmanager concepts.
pickerAttributes.xml XML file You should use this file to customize the search criteria
attributes for an object type for your picker.
Runtime location: <WT_HOME>\codebase\
pickerAttributes.xml
searchClientResource.rb RBINFO file You should use this file to localize the contents of the
Info pickers.
Runtime location: <WT_HOME>\src\com\ptc\
windchill\enterprise\search\client\
searchClientResource.rbInfo
itemPicker.tag Custom JSP tag file This file is contains the information about the
supported parameters for this tag.
Runtime location: <WT_HOME>\codebase\WEB-
INF\tags\itemPicker.tag
SearchableTypes.proper xconf Properties file You should specify component Id and corresponding
ties.xconf object types in this file and then run xconfmanager.
Runtime location:
<WT_HOME>\codebase\com\ptc\windchill\
enterprise\search\server\
SearchableTypes.properties.xconf
Note: You want to disable the type picker in the Item Picker.
</tr>
Possible
Parameter Default Value Values Req? Description
pickedDataF <WebApp>/net URL location of No URL of the data fetcher file that will be
etcher markets/jsp/sear the fetcher file used by the AJAX call to process the
ch/pickedData.js selected results.
p.
displayAttrib name Any attribute No Name of the attribute that should be the
ute displayed in the picker textbox after
selecting result from the item picker
baseWhereC “” (blank) Any valid I*E No Additional where clause if you want to
lause where clause filter search results on some specific
query criteria regardless of user input. This
where clause will just get “ANDed” with
the internal where clause. If you want to
specify different baseWhereClause for
say, Part and Document, then you can do
so using following syntax:
wt.part.WTPart$SEP$<where clause
that will get ANDed with internal
whereClause>$OBJ$wt.doc.WTDocum
ent$SEP$<where clause that will get
ANDed with internal whereClause>. If
you don’t specify the object type then
the one supplied will be used for all the
object type.
searchResult “”(blank) Any valid view id No This parameter allows user to define
sViewId custom view id for the picker search
results table.
customAcces “” (blank) Any valid name No This parameter is used to define your
sController own custom access controller. This
parameter would accept the complete
class name as the value. To specify
multiple customAccessController you
can pass on comma (,) separated list of
the class names.
Configuring Item Picker with your own typeComponentId in the type picker
<wctags:itemPicker id="itemPicker" typeComponentId="
Foundation.myPickerComponentId" />
{
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;
}
}
Objective
Background
The organization picker is used when you have a requirement to select specific organiza-
tion(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 orga-
nization 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 “/net-
markets/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 organization picker. After clicking Find… button, user 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 RBINFO file customizations.
• Windchill xconfmanager concepts.
Default Possible
Parameter Value Values Req? Description
defaultValue “” (blank) Any values No Default value for textbox rendered by the
picker.
pickedDataFetcher <WebApp URL location of No URL of the data fetcher file that will be
>/netmark the fetcher file used by the AJAX call to process the
ets/jsp/sear selected results.
ch/picked
Data.jsp.
displayAttribute Name Any attribute No Name of the attribute that should be the
displayed in the picker textbox after
selecting result from the organization
picker
baseWhereClause “” (blank) Any valid I*E No Additional where clause if you want to
where clause filter search results on some specific
query criteria regardless of user input. This
where clause will just get “ANDed” with
the internal where clause.
pickerType search search/picker No This parameter defines the picker type i.e.
“search” picker or “picker” picker. In
search picker, you will see search criteria
in the picker and then you have to hit the
search button to see the results however in
case of “picker” picker you will directly
see the results table without any search
criteria.
searchResultsView “”(blank) Any valid view id No This parameter allows user to define
Id custom view id for the picker search
results table.
customAccessCont “” (blank) Any valid name No This parameter is used to define your own
roller custom access controller. This parameter
would accept the complete class name as
the value. To specify multiple
customAccessController you can pass on
comma (,) separated list of the class
names.
{
var updateHiddenField = document.getElementById(pickerID);
var updateDisplayField = document.getElementById(pickerID +
"$label$");
var myJSONObjects = objects.pickedObject;
In the above example a simple drop down type picker is defined with.
Attributes:
• Id - This is required attribute used to distinguish between multiple Type-
Pickers
• Label - Picker Label
• Mode – Defines the mode in which the picker can be used. Default is
SEARCH.
There are other optional attributes for this picker which are listed at the end of this
section.
Parameters:
• Select – It has two possible values single and multi. Default is single.
Tree Format
In the tree format implementation the Picker Label, the Target element and find
button are displayed. On the find button click event a popup window pops up with
Windchill Type Identifiers displayed in tree format. If one or more types are
selected and ok button is hit the selected value(s) are populated in to target
element. If any type identifiers are present in the target element and user hits the
find button then the type identifiers in the target element appear as pre-selected
values in the tree, provided that the types are valid logical or external
representation of Windchill Type Identifiers. If cancel button is hit in the popup
Example:
<p:typePicker id="document_typePicker" label="Type : ">
<p:pickerParam name="format" value="tree" />
<p:pickerParam name="defaultType" value="wt.doc.WTDocument|
com.ptc.www.Agenda" />
<p:pickerParam name="defaultType" value="wt.doc.WTDocument|
com.ptc.www.Plan" />
<p:pickerParam name="defaultType" value="WCTYPE|
wt.pdmlink.PDMLinkProduct|Sub Product3" />
<p:pickerParam name="seedType" value="wt.doc.WTDocument" />
<p:pickerParam name="type" value="BOTH" />
<p:pickerParam name="showRoot" value="true" />
<p:pickerParam name="appOption" value="Mera Type$WCTYPE|
wt.pdmlink.PDMLinkProduct|Sub Product3" />
</p:typePicker>
Overview
The TypePicker is defined with the help of TypePicker Tag. The attribute and
parameter values supplied are used to populate an object of type TypeBean. This
bean is used to carry the user-supplied information across. The different phases
involved in a TypePicker component are as follows.
Ok Wizard action
• If no element is selected, a JavaScript warning is displayed and the pop-up
stays.</font></font>
• If some element is selected then it makes an Ajax call to the jsp specified via
the “pickerDataFetcher”. The jsp will fetch all the selected elements that need
to be populated in the target element.
• Calls “pickerCallBack” available in the calling jsp
• Update Target Element
• Close the pop-up
field field ="${target_element}" Target Element into which the picked element
attribute will be populated. It should be a
subclass of
com.ptc.core.components.rendering.AbstractG
uiComponent. Currently support TextBox and
ComboBox. If not supplied the component will
create a Target Element for the user
objectType objectType =" typepicker" This is the objecttype in which the picker action
is specified in *actions.xml (<Windchill>\
codebase\config\actions\EnterpriseUI-
actions.xml)
actionName actionName =" typePicker" This is the action name that is specified in
*actions.xml for the picker action
The Following table describes all the supported parameters of a Type Picker
Common Component.
select value ="single" Possible values are single and multi, the
former being the default.
Tag Definition
• \ClientArchitecture\CommonComponents\src_web\WEB-INF\tlds\picker.tld
• \wcEnterprise\EnterpriseUI\src_web\com\ptc\windchill\enterprise\tags\
picker\TypePickerTag.java
JSP files
• \wcEnterprise\EnterpriseUI\src_web\netmarkets\jsp\typepicker\
typePicker.jsp
• \wcEnterprise\EnterpriseUI\src_web\netmarkets\jsp\typepicker\
typePicker_dataFetcher.jsp
• \wcEnterprise\EnterpriseUI\src_web\netmarkets\jsp\typepicker\
typePicker_doer.jspf
• \wcEnterprise\EnterpriseUI\src_web\netmarkets\jsp\typepicker\
typePicker_includes.jspf
Objective
You want to pick User(s) based on certain search criteria.
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 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 Button along with the specified label after
using the tags for user picker. After clicking Find… button, 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 RBINFO file customizations.
• Windchill xconfmanager concepts.
Possible
Parameter Default Value values Req? Description
Objective
Participant Picker gives you the ability to search for participants using a variety of
search criteria and gives the ability to pick selective participants.
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.
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.
Intended Outcome
The selected participants are either populated in Windchill Client Architecture
table, or a populated in text box of Property Picker.
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.
Solution Elements
Customization Points
Possible
Parameter Default Value Values Req? Description
emailAllowed “false” “true”/ “false” No Not all clients will allow an email
string to be returned from the
picker, some clients will only allow
Principal objects to be returned.
singleParticipantT Empty “true”/ “false” No Not all clients that will use the
ype picker will need the same set of
Principal types. Some clients may
only except certain types to be
returned from the picker
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");
associationMap.put("PROJECT MANAGER", "Project Manager");
%>
<c:set var="associationMap" value="<%= associationMap %>"/>
<c:set var="participantType" value="<%= PrincipalBean.USER
%>"/>
<jca:participantPicker
actionClass="com.ptc.netmarkets.principal.NmPrincipalCommands2"
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 NmPrincipalCommands2 implements Externalizable {
public static ArrayList addPrincipal( NmCommandBean cb )
throws WTException {
ArrayList list = new ArrayList();
String users =
cb.getTextParameter(PrincipalBean.PARAM_SELECTED_PRINCIPALS);
if (users != null) {
int start = 0;
int pos = users.indexOf("#", start);
while (pos != -1) {
String user = users.substring(start, pos);
list.add(user);
start = pos+1;
pos = users.indexOf("#", start);
}
String role =
cb.getTextParameter(PrincipalBean.PARAM_ASSOCIATION);
ArrayList result = NmRoleHelper.service.addUsersToRole(cb,
role, list);
}
return result;
}
}
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
function that will be invoked by the picker to send back the picked values from
any picker. Property Picker also has an ability to define custom JavaScript
function that can be invoked by pickers. For example:
<p:propertyPicker label="${label}" field="${textbox}"
action="participantPickerSample2" type="participantpicker">
<p:populate from="${displayAttribute}"
to="${displayFieldId}" />
<p:populate from="oid" to="${id}" />
<p:pickerParam name="pickerId" value="${id}" />
<p:pickerParam name="objectType" value="wt.org.WTGroup" />
<p:pickerParam name="componentId" value="${componentId}" />
<p:pickerParam name="pickedDataFetcher"
value="${pickedDataFetcher}" />
<p:pickerParam name="pickerCallback"
value="${pickerCallBack}" />
<p:pickerParam name="containerRef" value="${containerRef}"
/>
<p:pickerParam name="baseWhereClause"
value="${baseWhereClause}" />
<p:pickerParam name="pickerTitle" value="${pickerTitle}" />
<p:pickerParam name="multiSelect" value="${multiSelect}" />
</p:propertyPicker>
actionMethod="JavaScript:${pickerCallback}()"
participantType="<%= PrincipalBean.GROUP %>"
<jca:participantPicker>
Topic Page
Configuring a Picker to Offer Only Specific Soft Types Based on User-specified
Criteria including Restricted Life Cycle States.................................................18-2
Building a Picker that Enables Users to Select Projects from an External Project
DB .....................................................................................................................18-8
Pickers from table toolbar ...............................................................................18-13
Generating HTML Tags for ProductView Visualization Within a JSP Page .18-16
18-1
Configuring a Picker to Offer Only Specific Soft Types
Based on User-specified Criteria including Restricted Life
Cycle States
Objective
Configure a picker to only display a specific soft-type of parts (Datecode
Release). Allow user to enter criteria which includes name, library and lifecycle
state. The states shown to the user must only be ones that represent a state that the
objects can have, not all LC states in the system. The user to be able to pick a
value for the attribute "Release Stream" (Windchill 8.0, 9.0, etc). The picker
should show the datecode name, not show its number, and also include the library
that contains the part. The picker will be used in the process to create Affected
Data relationships for a Change Request.
Associated requirements:
• Invoking a picker with customized seeded criteria.
• Customizing the columns of a table
Background
Problem scenario represents common customization scenario for Item Picker.
Picker is common UI component used for searching for referenced objects and
selecting one or more of them on calling application. You can customize criteria
attributes and result table columns shown in picker. You can configure Item
Picker to search for single or multiple object types. You can restrict search to only
in particular container or container types.
Scope/Applicability/Assumptions
• Item Picker can be launched from any JSP page using ItemPicker tag.
• Picker returns picked objects as a Jason object by calling JavaScript function
on calling page.
• It is the responsibility of calling page to further act on this Jason object.
• Soft type of Part is Date code so it’s fully qualified external form would be
like WCTYPE|wt.part.WTPart|org.r_and_d.DatecodeRelese
Intended Outcome
Datecode Release picker with Name, context and State as criteria attributes:
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Using JSP tags
• Using xconfManager
• Updating XML document.
• Using rbInfo files
Solution Elements
Procedure – Launch Item Picker with custom criteria and result table to pick DateCodeRelease
objects
<tr>
</tr>
….
<ComponentID id="test.Customization">
<ObjectType id="WCTYPE|wt.part.WTPart|
org.r_and_d.myPart">
<SearchCriteriaAttributes>
<Attributes>
<Name>name</Name>
<DisplayName>NAME_LABEL</DisplayName>
<IsSearchable>true</IsSearchable>
</Attributes>
<Attributes>
<Name>containerRef</Name>
<DisplayName>CONTEXT_LABEL</DisplayName>
<IsSearchable>false</IsSearchable>
</Attributes>
<Attributes>
<Name>state.state</Name>
<DisplayName>STATE_LABEL</DisplayName>
<IsSearchable>true</IsSearchable>
</Attributes>
</SearchCriteriaAttributes>
</ObjectType>
</ComponentID>
</PickerAttributes>
Here we have defined search criteria attributes as name, context and state.
DisplayName is resolved from rbInfo file : com\ptc\windchill\enterprise\search\
client\searchClientResource.rbInfo
<Option
serviceClass="com.ptc.netmarkets.search.views.CustomizedPartView"
requestor="java.lang.Object" selector="
wt.part.WTPart.customizedSearchView "/>
</Service>
Customization Points
Please refer [Item Picker Best Practice] for further customizing Item Picker.
Limitations
As per current implementation, Lifecycle State is not limited only to states that the
object can have.
Sample Code
<%@ taglib prefix="wctags" tagdir="/WEB-INF/tags" %>
<HTML>
<BODY><TABLE>
<tr>
</tr>
</BODY></TABLE>
</HTML>
Background
Configure a picker to talk to a non-Windchill database to fetch and display data. A
user should be able to search the ProjDB database from Windchill to search for
projects. It’s only expected to get back the Project Id, Name and Title OR Short
Description
Scope/Applicability/Assumptions
Since we are dealing with non-Windchill objects here, there are a number of
points that we need to take care of while implementation.
• First thing is an assumption that user will be able to write a task or a webject
which will fetch data from a non-Windchill database and yet return an IE
Group. The framework requires an IE Group to render results.
• Since the records returned are not Windchill objects, the user will have to
build a few attributes which are not exactly related to the data like “NmOid”.
• A user would have a JSP client from which to launch this picker
Intended Outcome
You should see a text box and Find Button along with the specified label after
using the tags for user picker.
Since we need an object type for launching a generic picker as a required attribute
we would be using wt.fc.Persistable. However this doesn’t interfere with the
working of the picker. It’s just given to launch a generic picker.
Solution
Use the ProjDb Picker Common Component in your JSP file to include ProjDB
Picker in your application.
Prerequisite knowledge
To achieve this objective, you need to have a thorough understanding of the
following:
• Basic development involving HTML forms, JSP, XML.
• Knowledge of writing a task and a webject to get data from a non-Windchill
database
• Picker common components
• Table common component
• View creation
• Knowledge of Customizing the view to display and use data correctly from
non-Windchill objects
• Knowledge of writing a data utility to fetch NmOid object
Procedure – Launching and configuring a Generic Picker for searching non-Windchill data like
ProjDB Projects
These attributes to the tag contain configuration information like, which view is
configured for this picker search result table, what is the data fetcher jsp to be
called etc.
<ObjectType id="wt.fc.Persistable">
<SearchCriteriaAttributes>
<Attributes>
<Name>projId</Name>
<DisplayName>Project ID</DisplayName>
<IsSearchable>true</IsSearchable>
</Attributes>
</ObjectType>
</ComponentID>
Writing a data utility to get NmOid column in the results table to display a check box for selection
Since we are dealing with non-Windchill objects here, we need to populate this
NmOid column by writing a special data utility. This data utility will have to be
configured in the components.datautilities.properties file, for the specified
searchResultsViewId as follows –
<!—ProjDB Picker Results Table -->
<Option serviceClass="
com.ptc.netmarkets.search.utils.ProjDbPickerNmObjectDataUtility "
requestor="java.lang.Object"
Sample Code
Objective
You want to a picker from table toolbar actions.
Background
The pickers from table toolbar are used when you have a requirement to launch
pickers from some table level action and accordingly populate the tables or do
some processing based on the results.
Scope/Applicability/Assumptions
Say you want to launch <your picker> from your table. It is assumed that your
action jsp file <MyPage>.jsp file in which you are putting picker tag includes
“/netmarkets/jsp/begin.jspf” or “/netmarkets/jsp/beginPopuf.jspf” file and
“/netmarkets/jsp/end.jspf” files.
Intended Outcome
On click of the action, you should see the corresponding picker getting launched.
Solution
Use the specific picker Common Component in your JSP file to include the 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 RBINFO files customization.
• Windchill xconfmanager concepts.
<your picker>.tag Custom JSP tag file This file is contains the
information about the supported
parameters for this tag.
Runtime location:
<WT_HOME>\codebase\ WEB-
INF\tags\<your picker>.tag
</tr>
Customization Points
Please refer to the <specific picker> Best Practice document for details regarding
the parameters.
multiSelect=”true”
Example usage:
// comp.ptc.wvs.common.ui.VisualizationHelper is assumed to be imported.
VisualizationHelper visHelper = newVisualizationHelper();
if (visHelper.isWVSEnabled()) //only execute code if WVS is enabled
{
// Embed the create dialog JavaScript somewhere in returned HTML.
// The below is just an example of calling it. Placement within
// HTML is the responsibility of the implementer.
out.println(visHelper.getCreateDialogWindow());
This chapter describes how to customize the Product Structure Explorer (PSE).
Topic Page
Customizing PSE Menus, Toolbars and Popup Menus.....................................19-2
Customizing PSE Table Display .......................................................................19-8
Customizing PSE for Soft Types.....................................................................19-13
Customizing PSE to Handle Modeled Subclasses ..........................................19-24
Customizing PSE Structure Queries................................................................19-31
Customizing Attribute Displays within Section Headings..............................19-35
Customizing Tabs - Configure Existing Tabs with Subtabs ...........................19-43
Allow Additional Steps During New Object Creation....................................19-45
Type Picker Display Customization................................................................19-47
Disabling Actions by Object Type ..................................................................19-49
Creating a Requirements Tab ..........................................................................19-51
Configurable Link Tables................................................................................19-67
19-1
Customizing PSE Menus, Toolbars and Popup Menus
Objective
You want to change the content of a PSE menu, toolbar or popup menu.
Background
The definition of the PSE Menus, Toolbars and popup menus are interconnected.
The definition of the user interface actions that appear in the toolbars and popup
menus is inherited from the ActionAccess definition of the Menu Bar.
The Menu Bar and Menu Items that are displayed do not change based on the
mode (“edit”, “draft” or “annotate”) in which PSE is working, though items may
become disabled if they are not relevant for the mode. The Toolbar does change
based on the mode, as do the popup menus exposed in the tables. Only menu items
that have an icon associated can appear in a toolbar.
In the Task Tabs of PSE, a number of tables are defined, which have tool bars and
popup menus. These are implemented in the exact same way as the main menu bar
via ActionAccess definitions, but the menus are not displayed.
Scope/Applicability/Assumptions
Intended Outcome
You may want to change the content of the toolbar for a given mode; for example
you may want to add the “New Query” Icon to the toolbar (before the Help icon)
that is displayed in Draft Mode for the main PSE window, and also to add the
actions “Insert Existing” and “Insert New” to the Uses Tab popup menu:
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Management of XML file customizations
Solution Elements
PDMLinkExplorerMenus.xml XML file Holds the definition of the main PSE Application
Menus, toolbars and popup menus that appear in
the tree displays.
Located in:
<Windchill>/codebase/config/logicreposito
ry/xml/explorer/productstructure
ExplorerMenuItems.xml XML file Holds Menu Item definitions, referenced from the
main application menu
(PDMLinkExplorerMenus.xml) and
ExplorerMenus.xml
Located in:
<Windchill>/codebase/config/logicreposito
ry/xml/explorer/structureexplorer
ExplorerMenusForAttributeTa XML file Holds the definition of the toolbars and popup
ble.xml menus for the Attribute Table on the Information
Tab.
Located in:
<Windchill>/codebase/config/logicreposito
ry/xml/explorer/structureexplorer
ExplorerMenusForDocuments XML file Holds the definition of the toolbars and popup
Tab.xml menus for the tables on the Documents Tab.
Located in:
<Windchill>/codebase/config/logicreposito
ry/xml/explorer/structureexplorer
ExplorerMenusForReplacemen XML file Holds the definition of the toolbars and popup
tsTab.xml menus for all tables on the Replacements Tab.
Located in:
<Windchill>/codebase/config/logicreposito
ry/xml/explorer/structureexplorer
ExplorerMenusForUsesTab.x XML file Holds the definition of the toolbars and popup
ml menus for all tables on the Uses Tab.
Located in:
<Windchill>/codebase/config/logicreposito
ry/xml/explorer/structureexplorer
This results in the New Query icon appearing in the toolbar as shown in Section
Intended Outcome.
Customization Points
Limitations
Adding new MenuItems to Menus, Toolbar or Popup menus for actions that are
not defined is not supported, as PSE currently has no supported API to allow
custom actions to be created. Also adding actions to tables for which they are not
designed is not supported.
Objective
You wish to change the default display order of columns in a PSE table, whether a
specific column is mandatory or optional, or whether a column is frozen.
Background
With Windchill PDMLink Rev 9, PSE now provides the capability for users to
customize the display of columns in tables. For example the Columns Details for
the Uses Tab.
However, what a user can do is controlled within the bounds set in the PSE XML
files that define the columns in each table.
Scope/Applicability/Assumptions
As these changes are being made to the PSE XML files, they will apply to all
users of PSE.
Intended Outcome
The Rev 9 default display is that Number is a frozen mandatory column that is
frozen (so it does not scroll) in the Uses Tab. Lets consider that we wish that
Name is a mandatory attribute to display, that it and Reference Designator Range
are frozen columns, Number is not frozen and is displayed though optional, Line
Number is available but not displayed. As Number is optional, it will be removed
from the tabular input search.
Solution
The CellDefinition element used in the PSE XML files has a number of attributes
that control the display of columns in a table and dictate to what extent a user can
change the table’s appearance and behavior.
Attribute Description
Many of the PSE Tables including the Uses Tab Table are defined in the file
<Windchill>/codebase/config/logicrepository/xml/explorer/structure
explorer/ExplorerForTablesAndPanels.xml
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Management of XML file customizations
ExplorerForTablesAndPanels.xml XML file Holds the definition of the tables and panels.
Located in:
<Windchill>/codebase/config/logicrepo
sitory/xml/structureexplore
Procedure
The Table id ptc.wnc.exp.PartUsesLinkTabTable in the file:
<Windchill>/codebase/config/logicrepository/xml/explorer/structureexplorer/Exp
lorerForTablesAndPanels.xml
is used to show the Uses Table BOM, when showing occurrences
ptc.wnc.exp.PartUsesOccTabTable us used.
By change the order of the CellDefinitions for the Table, and specifying
appropriate values for mandatory, displayWhen NoPreferenceSet, pinnable,
pinned and usedByTabularInput, the desired table can be formed.
<Table id="ptc.wnc.exp.PartUsesLinkTabTable"
selectionMode="multi-non-contiguous" displayMode="view">
<CellDefinition id="referenceDesignatorRange"
pinned="true" mandatory="false" displayModeOverride="edit">
<Label>
<Resource key="referenceDesignatorRangeLabel"/>
</Label>
<AttributeDefinition
attributeId="referenceDesignatorRange">
<Import id="ptc.wnc.exp.RefDesRangeAttrAction"/>
</AttributeDefinition>
</CellDefinition>
rendererClass="com.ptc.windchill.explorer.structureexplorer.render
er.component.LineNumberComponent">
<Import id="ptc.wnc.exp.LineNumberAttrAction"/>
</AttributeDefinition>
</CellDefinition>
After this change has been made, the method server has to be re-started. The client
UI may still not appear correct, this is because a user preference is used to hold the
current table layout. To clear this use the File->Preference action and reset the
column/window layout preferences. When PSE is restarted, the Uses Tab table
should appear as shown in the Intended Outcome section on 19-8.
Customization Points
The definition of the PSE Structure with id “ptc.pdm.pse.ExplorerTreeTable” is to
be found in:
Also, if Windchill Supplier Management is installed, its tables are defined in:
<Windchill>/codebase\config\logicrepository\xml\explorer\
productstructure\ExplorerForTablesAndPanelsForSUMA.xml
Other Resources
Objective
You have used the Attribute and Type Manager to define soft types of WTPart
and possibly added attributes to WTPartUsageLink. Although these types and
attributes typically appear in PSE without customization, you wish to control the
display of these attributes in the PSE UI.
Background
The selection of a type of Part in PSE typically automatically detects if soft types
have been defined with the Type Manager. Attributes will automatically be
prompted for, and displayed. This is achieved in the PSE XML files by entries
referencing attribute definitions with id’s of:
• ALL_SOFT_SCHEMA_ATTRIBUTES
• ALL_SOFT_CLASSIFICATION_ATTRIBUTES
• ALL_SOFT_USAGE_LINK_SCHEMA_ATTRIBUTES
Although these entries are useful, it is not possible to control the order of display.
Also, some values may get set programmatically on the server, and so the user
should not be allowed to specify values.
Consider the simple example where WTPart has had an IBA myDescription added
to the base definition. A myMechanical Part has been defined in the Type
Manager with attributes of myCost and myWeight, WTPartUsageLink has been
extended to have an IBA of myColor.
The steps to insert a new myMechanical Part into an assembly would result in
these screens.
After the Name and other properties have been specified, the last step in the
wizard will prompt for the IBA’s, although the Attribute column can be sorted, the
default order is not controlled.
The info Tab for myMechanical Part presents all attributes, but not in any sort of
order. The attributes in the upper part of the display represent the fixed set
applicable to identify that object; some of these may not be relevant. The
attributes in the lower editable table include attributes inherited from WTPart and
are in no controlled order.
Scope/Applicability/Assumptions
As these changes are being made to the PSE XML files, they will apply to all
users of PSE.
Intended Outcome
Considering the example described above.
When specifying the attributes of the New Part, the attributes in the last step of the
wizard appear in the order defined in the PSE XML.
The attributes in the lower table of the Information Tab can also be ordered.
The Uses BOM Table can be configured to show the Usage Link attribute.
Solution
For the dataType, defined a new ExplorerElementGroup with the context
application of “ptc.wnc.StructureExplorer”. Within this element define the
contents of the Attribute Tables.
It is likely that if you are doing this customization you have many types of
WTPart defined. Although these element definitions can be added to the file
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
The management of XML file customizations
Solution Elements
ExplorerForTableAndPanels.xml XML file Holds the definition of the PSE Tables and
panels
Located in:
<Windchill>/codebase/config/logicrepo
sitory/xml/structureexplore
LogicContext XML element Specifies the application and data type that the
definition is to be applied
Procedure
Either create a new file representing the Soft Part (myMechanical.xml) in the
directory:
Windchill>/codebase/config/logicrepository/xml/explorer/structuree
xplorer
<ExplorerElementGroup>
<LogicContext application="ptc.wnc.StructureExplorer"
dataType="com.aprilia.www.myMechanical"/>
<AttributeTable id="ptc.wnc.exp.CreatePartTab3">
<Table id="Table" displayMode="edit">
<!-- These 3 entries remove the inherited entries from
WTPart -->
<CellDefinition id="ALL_SOFT_SCHEMA_ATTRIBUTES">
<Placement remove="true"/>
</CellDefinition>
<CellDefinition id="ALL_SOFT_CLASSIFICATION_ATTRIBUTES">
<Placement remove="true"/>
</CellDefinition>
<CellDefinition
id="ALL_SOFT_USAGE_LINK_SCHEMA_ATTRIBUTES">
<Placement remove="true"/>
</CellDefinition>
<AttributeTable
id="ptc.wnc.exp.CreatePartNoUsageLinkTab3">
<Table id="Table" displayMode="edit">
<AttributeTable id="ptc.wnc.exp.EditPropertiesTable">
<Table id="Table" displayMode="edit">
</ExplorerElementGroup>
</LogicRepository>
This results in the attributes being requested in the Wizard and Information Tab as
shown in Section Intended Outcome.
To add the IBA to the Uses Tab, edit:
Windchill>/codebase/config/logicrepository/xml/explorer/structuree
xplorer/ExplorerForTablesAndPanels.xml
The method server will need to be re-started in order that these changes are
applied.
Further customization
To extend the above example, consider adding the “myDescription” attribute to
the Uses Tab. When editing this String attribute, the user may want to specify
many characters, however to perform this in the space of the cell in a table is not
easy. So, it is possible to associate a different renderer to this attribute that will
popup a dialog when editing the value, allow the user to enter many lines of text.
Edit:
Windchill>/codebase/config/logicrepository/xml/explorer/structuree
xplorer/ExplorerForTablesAndPanels.xml
Just using the Golf Cart as an example, this will result in the following dialog
being presented when the “…” button is selected in the
cell.
This renderer could also be applied to the attributes in the Information Tab.
Objective
You have created a custom modeled business object; you want to customize the
PSE so that it will fully support your modeled subclass.
Scope/Applicability/Assumptions
You have separately created your modeled subclass.
Intended Outcome
Instances of your modeled subclass will be detected and presented by PSE in the
same manner as out-of-the-box modeled objects.
Solution
Make changes in the following three areas:
• LogicalAttributes.xml
• PSE Tables and Panels
• Customized command delegates
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• The management of XML file customizations
• The management of RBINFO file customizations
Solution Elements
Note: When specifying new modeled attributes that are defined only for subclass
objects, the corresponding "AttributeGroup" or “AttributeTable” or "Table”
defined in a "wt.part.WTPart" context should be copied to the appropriate
subclass context.
A good practice when adding element groups for customized objects is to put all
customized changes in a separate file, rather than edit existing files. Name them
consistently, e.g. CustomExplorerForTablesAndPanels.xml.
Using the previous example of "ext.cust.CustPart" extends "wt.part.WTPart", the
following AttributeGroup
<ExplorerElementGroup>
<LogicContext application="ptc.wnc.StructureExplorer"
dataType="wt.part.WTPart"/>
<AttributeGroup id="ptc.wnc.exp.ViewPropertiesPanel" displayMode="view">
<CellDefinition id="number">
<AttributeDefinition attributeId="number"/>
</CellDefinition>
<CellDefinition id="organizationIdentifier">
<AttributeDefinition attributeId="organizationIdentifier"/>
</CellDefinition>
<CellDefinition id="name">
<AttributeDefinition attributeId="name"/>
</CellDefinition>
<CellDefinition id="versionIterationView">
<AttributeDefinition attributeId="versionIterationView"/>
</CellDefinition>
...
</AttributeGroup>
</ElementGroup>
should be copied under the LogicContext for "ext.cust.CustPart" like this:
<ExplorerElementGroup>
<LogicContext application="ptc.wnc.StructureExplorer"
dataType=" ext.cust.CustPart "/>
<AttributeGroup id="ptc.wnc.exp.ViewPropertiesPanel" displayMode="view">
<!-- name and number will inherit from WTPart -->
This document illustrates the steps with a simple example: a custom part class
“MyPart” that extends wt.part.WTPart with a single string attribute “myAttr”.
try {
new_copy.setMyAttr(original.getMyAttr());
}
catch (WTPropertyVetoException e) {
throw new WTException(e);
}
}
return new_copy;
//##end newCopy%461E645C0050f.body
CopyMyPartDelegate/singleton
Customization Points
Caution: When working with RBINFO files, follow the practices recommended
in the Managing Customizations chapter starting on page 5-1, for example
Changing Displayed Text Found in RBINFO Files.
Each modeled object has an associated RBINFO file, created during generation,
that contains localized strings that are used as the labels for attributes and columns
in PSE. If the label needs to be changed, the corresponding RBIFNO file should
be edited. For example, in the file CustPartModelRB.rbInfo, to change the label
for the attribute "booleanMBA", edit the following line:
CustPart.booleanMBA.value=New Label for booleanMBA
Modeled enumerations will display the internal values of the enumerations, when
rendered as a drop-down menu in PSE. To change the labels displayed in a drop-
down menu, the corresponding RBINFO file for the enumeration should be
edited. For example, if you generate a class, "public final class MyEnum extends
More information can be found in the Enumerated Types chapter on page 34-1.
Other Resources
• Customizing PSE Table Display on page 19-8
Objective
You want to customize the PSE New Query dialog to include soft types of
WTPart and allow queries to be created referencing IBA’s of the soft type.
Background
The dialog launched from the View->Query->New Query menu entry allows the
user to construct a query that will locate objects in the structure that match the
specified criteria. The out-of-the-box configuration allows specific attributes of
WTPart to be queried.
Customers will create their own soft types of WTPart with their own attributes. In
order to allow these to be used in the query, customization of the PSE XML files
is required.
Scope/Applicability/Assumptions
As these changes are being made to the PSE XML files, they will apply to all
users of PSE.
Intended Outcome
You may want to include the soft WTPart “myPart” in the searchable Types, and
allow the attributes “myCost” and “myDescription” to be queried. As “End Item”,
Solution
Add the appropriate element group in
<Windchill>/codebase/config/logicrepository/xml/explorer/structure
explorer/ExplorerSearchableTypes.xml
The element group will define CellDefinitions (both additions and removals) for
the AttributeGroup with id="ptc.wnc.exp.QuerySearchableAttrs " for the
“myPart” type.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• The management of XML file customizations
ExplorerSearchableTypes.xml XML file Holds the definition of types and attributes that
will be exposed in the New Query dialog.
Located in:
<Windchill>/codebase/config/logicreposi
tory/xml/structureexplore
LogicContext XML element Specifies the application and data type that the
definition is to be applied
AttributeGroup XML element PSE locates all the attribute groups with id
ptc.wnc.exp.QuerySearchableAttres, and uses
the type inheritance to find all the properties
(CellDefinitions) that will be displayed.
Procedure
Edit the file ExplorerSearchableTypes.xml, before the final line
</LogicRepository> insert the following lines:
<!-- New Query definition for soft type myPart -->
<ExplorerElementGroup>
<LogicContext application="ptc.wnc.StructureExplorer"
dataType="com.aprilia.www.myPart"/>
<AttributeGroup id="ptc.wnc.exp.QuerySearchableAttrs" displayMode="view">
<!-- Remove the following that would otherwise be inherited from WTPart
Definition -->
<CellDefinition id="endItem">
<Placement remove="true"/>
</CellDefinition>
<CellDefinition id="genericType”>
<Placement remove="true"/>
</CellDefinition>
<CellDefinition id="referenceDesignator">
<Placement remove="true"/>
</CellDefinition>
<!-- Add the specific attributes of myPart -->
<CellDefinition id="myCost">
<AttributeDefinition attributeId="com.aprilia.www.myCost"/>
</CellDefinition>
<CellDefinition id="myDescription">
<AttributeDefinition attributeId="com.aprilia.www.myDescription"/>
</CellDefinition>
</AttributeGroup>
</ExplorerElementGroup>
Customization Points
It is valid to remove the WTPart definition from ExplorerSearchableTypes.xml,
so Part does not appear in the type drop-down. However, no definitions of the
properties will be inherited by the soft type definitions, so these will have to be
added.
Other Resources
rendererClass="com.ptc.windchill.explorer.structureexplorer.render
er.component.PartNumberComponent"/>
</CellDefinition>
<SectionHeading allowAttrDetails="true">
<Label>
<Resource key="Properties 1"/>
</Label>
</SectionHeading>
<CellDefinition id="view">
<AttributeDefinition attributeId="view"
rendererClass="com.ptc.windchill.explorer.structureexplorer.render
er.component.ViewComponent"/>
</CellDefinition>
<CellDefinition id="folder">
<AttributeDefinition attributeId="folder"
rendererClass="com.ptc.windchill.explorer.structureexplorer.render
er.component.DefaultContainerFolderBrowserComponent"/>
For example, the user can choose to hide the Location attribute within the
Properties 1 section. This is now saved as a preference for this user and will stay
this way the next time the user loads PSE.
Sample Code:
<AttributeGroup id="ptc.wnc.exp.CreateChild" displayMode="edit">
<SectionHeading id="ptc.wnc.exp.CreateChild.Responsibilities"
allowAttrDetails="true" allowCollapsable="true">
<Label>
<Resource key="responsibilitiesSectionLabel"/>
</Label>
</SectionHeading>
</AttributeGroup>
• The Object Attributes tab shows only those attributes that are attached
directly to the selected part, not the link attributes.
The first line duplicates the id of the WizardList you want to modify. The second
line shows the addition of a new AttributeGroup inline, it could also be defined in
another place then imported here similar to the original WizardList definition.
The Placement segment indicates that your new AttributeGroup is to be shown
after CreateChildPartTab2.
You can also remove an AttributeGroup or AttributeTable from the original
WizardList that you don't want to use. For example, the following xml removes
the last step of the wizard (the AttributeTable that shows all the soft attributes):
<WizardList id="ptc.wnc.exp.CreateChildWizardList">
<AttributeTable id="ptc.wnc.exp.CreatePartTab3">
<Placement remove="true"/>
</AttributeTable>
</WizartList>
This example takes the existing AttributeGroup defined for the CreatePartTab2
step and adds the partType attribute before the endItem and removes the
genericType attribute. Note that CreatePartTab2 is imported into both the
CreateWizardList and the CreateChildWizardList so you will be modifying both
wizards.
Note: This change will be effective for ALL instances of the GUI panel for
the Type defined in the <LogicContext> element.
<TypeDefinition id="com.my.MyTypeBTD"
typeId="WCTYPE|wt.part.WTPart|org.my.MyTypeB"/>
<TypeDefinition id="com.my.MyTypeDTD"
typeId="WCTYPE|wt.part.WTPart|org.my.MyTypeD"/>
This configuration will disable the Edit Common Attributes action in the PSE
application whenever an part of type A, B or D is selected.
<TypeDefinition id="com.my.MyTypeBTD"
typeId="WCTYPE|wt.part.WTPart|org.my.MyTypeB"/>
<TypeDefinition id="com.my.MyTypeDTD"
typeId="WCTYPE|wt.part.WTPart|org.my.MyTypeD"/>
2. Locate the <TabSet> element and add an import for the new Requirements
tab, and place it in the desired location:
<TabSet id="ptc.pdm.pse.ExplorerTaskTabSet" tabPlacement="top"
tabIdWithFocus="ptc.wnc.exp.PropertiesTab">
2. After the <TabSet> element, define a <Tab> element for the Requirements
tab:
<TabSet id="ptc.pdm.pse.ExplorerTaskTabSet" ... >
...
</TabSet>
<Tab id="mycom.wnc.exp.RequirementsTab"
tabClass="com.ptc.windchill.explorer.structureexplorer.explorer
.tabs.ShowTablesTab"
enabledDeciderClass="com.mycom.windchill.explorer.structureexpl
orer.deciders.RequirementsEnabledDecider">
<Label imageName="wtcore/images/change_action.gif">
<Resource key="requirementsTabLabel"/>
</Label>
<Panel>
<Import id="mycom.pdm.pse.RequirementAssocTable"/>
</Panel>
</Tab>
Note:
• The id attribute for the Tab element must match the id specified in the import
sub-element of the <TabSet> element defined above.
• The class defined for the enabledDeciderClass attribute of the Tab element,
controls what types this tab will be enabled for when parts are selected in the
structure tree. This must be implemented by the customer.
• The imageName attribute of the <Label> sub-element defines the icon to
display on the tab.
• The <Resource> sub-element of <Label> refers to the defined text label for
the tab.
• The <Panel> element contains an import to the defined table to be displayed.
2. After the <Tab> element definition for the Requirements tab, define the
<AssociationTable> element.
<Tab id="mycom.wnc.exp.RequirementsTab" ... >
...
</Tab>
<AssociationTable
id="mycom.pdm.pse.mycom.pdm.pse.RequirementAssocTable">
<Label>
<Resource key="requirementsLabel"/>
</Label>
<Import id="mycom.wnc.exp.RequirementSAD"/>
<Import id="mycom.wnc.exp.ChangeActionTabTable"/>
<Import id="mycom.wnc.exp.ChangeActionAssocTableAA"/>
</AssociationTable>
Note:
2. Find the section in the file where the structure author definitions are defined.
After the last <StructureAuthorDefinition> element, add the following
definition for the Requirements:
<StructureAuthorDefinition id="mycom.wnc.exp.RequirementSAD">
<Import id="mycom.wnc.exp.PartToRequirementSD"/>
</StructureAuthorDefinition>
Note:
2. Find the section in the file where the structure definitions are defined. After
the last <StructureDefinition> element, add the following definition:
<StructureDefinitionSimple
id="mycom.wnc.exp.PartToRequirementSD"
parentToChild="addressedPartMasterReference"
childDisplayId="number">
<Import id="ptc.wnc.exp.WTPartTD"/>
</StructureDefinitionSimple>
Note:
<Table id="airbus.wnc.exp.ChangeActionTabTable"
selectionMode="multi-non-contiguous" displayMode="view">
<CellDefinition id="number" mandatory="true"
pinned="true">
<Label>
<Resource key="reqNumberLabel"/>
</Label>
<AttributeDefinition attributeId="number"/>
</CellDefinition>
<CellDefinition id="effVector" mandatory="true">
<Label>
<Resource key="reqValidityLabel"/>
</Label>
<AttributeDefinition
attributeId="displayEffectivity"/>
</CellDefinition>
<CellDefinition id="theActionState" mandatory="true">
<Label>
<Resource key="reqStatusLabel"/>
</Label>
<AttributeDefinition attributeId="theActionState"/>
</CellDefinition>
<CellDefinition id="owningChangeDirective"
mandatory="true">
<Label>
<Resource key="relatedCINLabel"/>
</Label>
<AttributeDefinition attributeId="MBA|
owningChangeDirectiveReference^WCTYPE|
wt.change2.WTChangeDirective~MBA|number"
rendererClass="com.ptc.windchill.explorer.structureexplorer.ren
derer.component.TypeIconifiedStringComponent"/>
</CellDefinition>
<CellDefinition id="satisfyPartMaster"
mandatory="true">
Note:
<ExplorerElementGroup>
<LogicContext
application="ptc.pdm.ProductStructureExplorer"/>
<ActionAccess id="mycom.wnc.exp.ChangeActionAssocTableAA">
<MenuBar id="MenuBar">
<Menu id="Menu">
<Import id="ptc.wnc.exp.InfoPageAssocMI"/>
<Separator/>
<MenuItem id="GenerateReqsMI">
<Label
imageName="com/ptc/windchill/explorer/config/images/child_creat
e.gif">
<Resource key="generateReqsLabel"/>
</Label>
<ToolTip>
<Resource key="generateReqsToolTip"/>
</ToolTip>
<Import
id="mycom.wnc.exp.GenerateRequirementsAction"/>
</MenuItem>
<MenuItem id="FulfillReqMI">
<ModeToolBar id="ToolBarA">
<Import id="ptc.wnc.exp.EditAppMode"/>
<MenuItemIdentifier
id="ptc.wnc.exp.InfoPageAssocMI"/>
<Separator/>
<MenuItemIdentifier id="GenerateReqsMI"/>
<MenuItemIdentifier id="FulfillReqMI"/>
<MenuItemIdentifier id="ViewEffLogMI"/>
</ModeToolBar>
<ModeToolBar id="ToolBarB">
<Import id="ptc.wnc.exp.DraftAppMode"/>
<Import id="ptc.wnc.exp.AnnotateAppMode"/>
<Import id="ptc.wnc.exp.ReadOnlyAppMode"/>
<MenuItemIdentifier
id="ptc.wnc.exp.InfoPageAssocMI"/>
<Separator/>
<ModePopupMenu id="PopupMenuA">
<Import id="ptc.wnc.exp.EditAppMode"/>
<MenuItemIdentifier id="GenerateReqsMI"/>
<MenuItemIdentifier id="FulfillReqMI"/>
<MenuItemIdentifier id="ViewEffLogMI"/>
</ModePopupMenu>
<ModePopupMenu id="PopupMenuB">
<Import id="ptc.wnc.exp.DraftAppMode"/>
<Import id="ptc.wnc.exp.AnnotateAppMode"/>
<MenuItemIdentifier id="GenerateReqsMI"/>
<MenuItemIdentifier id="FulfillReqMI"/>
<MenuItemIdentifier id="ViewEffLogMI"/>
<Separator/>
<MenuItemIdentifier id="RevertMI"/>
<MenuItemIdentifier
id="ptc.wnc.exp.CommentAssocMI"/>
</ModePopupMenu>
</ActionAccess>
</ExplorerElementGroup>
</LogicRepository>
Note:
• The id attribute for the <ActionAccess> element must match the id specified
in the import sub-element of the <AssociationTable> element defined above.
• The <Resource> sub-element of the <Label> and <Tooltip> elements refers to
the text label defined in the resource file to be used for column header.
Define the labels, tool tips and mnemonics for the Requirements tab
Define the text for the labels, tool tips and mnemonics used in the Requirements
tab.
1. Open the ConfigurationResource.rbInfo file from the following location:
<Windchill>/codebase/config/logicrepository/xml/explorer/produc
tstructure
generateReqsLabel.value=Generate Requirements
generateReqsToolTip.value=Generate Requirements
fulfillReqLabel.value=Fulfill Requirement
fulfillReqToolTip.value=Fulfill Requirement
Note:
• The property name defined in the file, e.g. <property name>.value, must
match the key attribute of the <Resource> element in the XML configuration
files.
actionClass="com.ptc.windchill.explorer.structureexplorer.panel
.actions.FulfillChangeActionForStructureWithIntermediateNodeAct
ion">
<StructureAuthorAction>
<Import id="mycom.wnc.exp.PartToRequirementSD"/>
</StructureAuthorAction>
<Import id="ptc.wnc.exp.IsValidInAllWithReadVAL"/>
</ActionDefinition>
Note:
Define the ActionDefinition Element for the Generate Change Actions Action
This will define the Action Definition element for the Generate Change Actions
action.
As detailed above, locate the <ExplorerElementGroup> element with a sub-
element <LogicContext> with the application attribute value of
'ptc.pdm.ProductStructureExplorer'. After the LogicContext element, add an
ActionDefinition element like the following:
<ActionDefinition id="mycom.wnc.exp.GenerateRequirementsAction"
actionClass="com.ptc.windchill.explorer.structureexplorer.panel
.actions.GenerateChangeActionsAction">
<Action/>
<Import id="ptc.wnc.exp.IsValidInAllVAL"/>
</ActionDefinition>
Define the ActionDefinition Element for the View Effectivity Log Action
This will define the Action Definition element for the View Effectivity Log
action.
As detailed above, locate the <ExplorerElementGroup> element with a sub-
element <LogicContext> with the application attribute value of
'ptc.pdm.ProductStructureExplorer'. After the LogicContext element, add an
ActionDefinition element like the following:
<ActionDefinition id="mycom.wnc.exp.ViewEffectivityLogAction"
actionClass="com.ptc.windchill.explorer.structureexplorer.panel
.actions.AssociationUrlAction">
<UrlAction selectionMode="single"
urlBaseName="servlet/TypeBasedIncludeServlet?">
<UrlParameter value="oid={selected_oid}"/>
</UrlAction>
<Import id="ptc.wnc.exp.IsValidForHTMLLaunchMasterOkVAL"/>
</ActionDefinition>
import java.util.ArrayList;
import java.util.List;
import
com.ptc.core.foundation.struct.common.StructureConstants;
import com.ptc.core.meta.common.AssociationIdentifier;
import com.ptc.core.meta.common.AssociationTypeIdentifier;
import com.ptc.core.meta.common.AttributeTypeIdentifier;
import com.ptc.core.meta.common.IdentifierFactory;
import com.ptc.core.meta.common.TypeIdentifier;
import com.ptc.core.meta.common.TypeInstanceIdentifier;
import com.ptc.core.meta.type.common.TypeInstance;
import
com.ptc.windchill.explorer.structureexplorer.config.AbstractCon
fig;
import
com.ptc.windchill.explorer.structureexplorer.deciders.EnabledDe
cider;
import
com.ptc.windchill.explorer.structureexplorer.utility.CommonData
;
static {
try
{
type_id_list.add(
(TypeIdentifier)identifierFactory.get(common_ancestry +
"com.mycom.CustomPartA")); //$NON-NLS-1$
type_id_list.add(
(TypeIdentifier)identifierFactory.get(common_ancestry +
"com.mycom.CustomPartB")); //$NON-NLS-1$
type_id_list.add(
(TypeIdentifier)identifierFactory.get(common_ancestry +
"com.mycom.CustomPartC")); //$NON-NLS-1$
type_id_list.add(
(TypeIdentifier)identifierFactory.get(common_ancestry +
"com.mycom.CustomPartD")); //$NON-NLS-1$
}
catch(Exception e)
if (node_ti != null)
{
enabled = isValidPart(node_ti);
}
return enabled;
}
/**
* is this node a generic part or a configurable generic
part?
**/
public static boolean isValidPart(TypeInstance node_ti)
{
if (node_ti == null)
{
return false;
}
TypeInstanceIdentifier node_tii = (TypeInstanceIdentifier)
node_ti.getIdentifier();
if (node_tii == null)
{
return false;
}
try
{
if (IsMastered(node_ti))
{
return false;
}
return false;
}
catch (Exception e)
/**
* Assumes an iteration...
*
* isMastered is an unpersisted Iteration and a persisted
Master.
* @param ti
* @return
*
*/
private static boolean IsMastered(TypeInstance ti)
{
try
{
TypeInstanceIdentifier tii = (TypeInstanceIdentifier)
ti.getIdentifier();
if (tii instanceof AssociationIdentifier)
{
tii = ((AssociationIdentifier) tii).getTail();
}
if (!tii.isInitialized())
{
AttributeTypeIdentifier master_ati =
(AttributeTypeIdentifier)
identifierFactory.get(StructureConstants.MASTER_REFERENCE_ID_ST
R, tii.getDefinitionIdentifier());
Object object = ti.getSingle(master_ati);
TypeInstanceIdentifier master_tii = null;
if (object instanceof TypeInstanceIdentifier)
{
master_tii = (TypeInstanceIdentifier) object;
}
if (master_tii.isInitialized())
{
return true;
}
}
}
catch (Exception ex)
{
return false;
}
return false;
}
Note: The load file loads both the link types and the association constraints.
• %WT_HOME%/codebase/config/actions/ConfigurableLinkExamples-
actionmodels.xml
• %WT_HOME%/codebase/config/actions/ConfigurableLinkExamples-
actions.xml
• %WT_HOME%/codebase/com/ptc/windchill/enterprise/object/configurableLink
ExamplesResource.class
The .rbinfo file ties the registry of the 3rd level navigation table to the link type
that is implemented for the table, the table header, and the action title.
• %WT_HOME%/codebase/com/ptc/windchill/enterprise/ConfigurableLinkExam
ples.xconf
• %WT_HOME%/codebase/com/ptc/windchill/enterprise/ConfigurableLinkExam
ples-wt.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 soft types.
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 grant the teamMembers permissions read, modify, create
and delete ConfigurableMastersLink objects. More specific rules can be
defined for soft types of ConfigurableMastersLink.
<AccessControlRule>
<domainName>/Default</domainName>
<externalTypeId>wt.configurablelink.ConfigurableMastersLink</ex
ternalTypeId>
<lifecycleState>ALL</lifecycleState>
<WTPrincipalReference isInternal="true">
<groupName>teamMembers</groupName>
<groupType>teamMembers</groupType>
</WTPrincipalReference>
Topic Page
Customizing Windchill MPMLink Overview...................................................20-2
General Windchill MPMLink Customizations..................................................20-5
Customizing the Process Plan Explorer ............................................................20-7
Customizing the Manufacturing Product Structure Explorer..........................20-23
20-1
Customizing Windchill MPMLink Overview
Windchill MPMLink is an add-on module to Windchill PDMLink and all
Windchill MPMLink explorers are built using the Product Structure Explorer
(PSE) infrastructure. Many of the customizations that can be done to Windchill
PDMLink, in particular customizations affecting the PSE, are propagated to
Windchill MPMLink. For more information on customizing Windchill PDMLink
and the PSE, refer to the relevant sections in this guide.
Additionally, many aspects of the way Windchill MPMLink appears and behaves
can be customized by using the Preferences Manager. Windchill MPMLink
preferences are located in the Product Structure Explorer section of the
Preferences Manager.
Any changes made to the XML configuration changes are applied when the
Method Server is restarted. To avoid having to restart the method server after each
configuration change activate the following property using Windchill Shell:
xconfmanager -d
com.ptc.windchill.explorer.monitorXmlConfigChanges=true -t
codebase/wt.properties
This property will automatically rebuild the jar that contains all XML
configurations. However you will need to restart your applet and clear your client
Java cache.
Any error in an XML file will prevent the jar from being built properly. To enable
logging in the Method Server console add the following line to the file codebase\
WEB-INF\log4jMethodServer.properties.
log4j.logger.com.ptc.core.logic.LogicRepository=DEBUG
Note: When moving to new versions of Windchill, changes in the XML files will
NOT be automatically migrated. Changes in these files should be clearly
documented. See Setting Up a Directory Structure for Managing Customized
Files and Text Tailoring in Chapter 5, "Managing Customizations" for more
detailed recommendations.
File Description
Tip: The following files are the default files recommended for customizing
Windchill MPMLink. New customization files can be created provided these files
use the same application ID:
codebase\config\logicrepository\xml\explorer\customization
To change the default unit for an individual attribute, such as time, cost or
dimension, use the Type and Attribute Manager.
• To change the default unit for a given attribute use the Attribute Definition
Manager tab. Navigate to the attribute you would like to change, and enter
the new value in the Override field.
The Formula Sets tab is used to select pre-defined formula sets that can be used
to calculate the time and cost associated with an operation. For example, a
standard time and cost formula set, and a periodic time and cost formula set.
These formula sets take into account the number of parts to be produced in the
operation and use the specifications defined for work center (For example, setup
time, queue time). Formulas and formula sets are used when the Calculate Time
and Cost action has been selected, and when you are loading process plans and
operations into the Manufacturing Gantt Explorer.
While multiple formula sets can be associated with a work center, one formula set
can be designated as the default formula set for the work center. It is this formula
set that is assigned to an operation when the work center is allocated to that
operation.
Note: Formulas must be assigned to a Formula set. If you do not have an existing
formula set, you must define one before you can define a custom formula. The
PSE can be customized to allow you to use the PSE to add additional values to
your customized formula sets. For more information, see the PSE documentation.
<csvformulaClassName>com.ptc.windchill.mpml.formula.Standard
AttributeValueFormula</csvformulaClassName>
<csvfolder>/Default/Design</csvfolder>
<csvparentContainerPath></csvparentContainerPath>
<csvorganizationName></csvorganizationName>
<csvorganizationID></csvorganizationID>
</csvFormulaMetaData>
3. Link the formula metadata to the formula set by using an attribute name.
For example, when the service to calculate the formula is called, all the
formula metadata associated to the formula set will be executed and a map of
all calculated values will be returned using the attribute name as the key.
When creating a java class that implements Formula interface, these inputs are
accessible out-of-the-box in the inputs map.
• FormulaHelper.FORMULAVALUATED: the object on which the formula
set is linked and that casts to ForumlaValuated.
• FormulatHelper.FORMULAVALUATED_TI: the object type instance on
which the formula set is linked and that casts to TypeInstance. It can be null.
• FormulaHelper.FORMULAVALUATED_ATTRIBUTE_NAME: the
attribute name used to link the formula meta data to the formula set and that
casts to String. This will be used as the key in the results map.
• FormulaHelper.LOT: the lot value specified by the user in the context of the
Calculate Time and Cost action. It casts to Double.
The following is an example of a formula java class:
import com.ptc.core.meta.common.AttributeIdentifier;
import com.ptc.core.meta.common.AttributeTypeIdentifier;
import com.ptc.core.meta.common.TypeinstanceIdentifier;
import
com.ptc.core.meta.container.common.AttributeContainerSpec
import com.ptc.core.meta.server.TypeIdentifierUtility;
import com.ptc.core.meta.type.common.TypeInstance;
import com.ptc.core.meta.type.common.TypeInstanceFactory;
import com.ptc.windchill.mpml.MPMLinkHelper;
import java.text.NumberFormat;
import java.util.HashMap;
import wt.units.FloatingPointWithUnits;
import wt.util.WTContext;
import util.WTException;
Note: It is also possible to add more input to the formula by creating a new action
and then using formula services to call the execution of the formula set. For more
information on creating new actions, see the PSE documentation.
com.ptc.windchill.mpml.CumulatedTimeAndCostActionCostUnit
Location Description
JSP Description
Property Description
Customizations Description
To change the time units for the steps Modify the following JSPs, as
in an operation: required:
setupTimeUnit
processingTimeUnit
laborTimeUnit
queueTimeUnit,
teardownTimeUnit,
waitTimeUnit,
moveTimeUnit
To change the font, size, or color of the Modify the following CSS file and the
titles in a work instruction: JSPs that use the definitions in the
CSS file:
workInstructionStyles.css
To change the logo at the top of the Use the following procedure:
work instruction, or in the operation xconfmanager -d
table:
com.ptc.windchill.mpml.WorkInst
ructionLogo=<logo> -t
codebase/wt.properties
<ExplorerElementGroup>
<LogicContext application="ptc.cust.ProcessPlanExplorer"
4. Clear your Java cache and restart the Process Plan Explorer.
In this example note that:
• The application ID used for this XML fragment is
ptc.cust.ProcessPlanExplorer. This is the one recommended application ID
for customizing the Process Plan Explorer.
• The default second creation wizard for the MPMOperation object,
ptc.mpm.exp.CreateTab2, is defined in:
• codebase\config\logicrepository\xml\explorer\mpmexplorer\
MPMExplorerForTablesAndPanels.xml.
• To add more attributes to the same creation wizard, the same AttributeGroup
ID, ptc.mpm.exp.CreateTab2, must be used.
• Only the cell definitions for the new attributes are added in this XML
segment.
Tip: By default cell definitions need to be added after the default cell definitions.
To specify a different location use the Placement tag.
<Placement insertKey="after|before"
insertId="attributeName"replace="true|false"/>
For example:
<CellDefinition id="inspectionNeeded">
<Label>
<Resource key="inspectionNeededLabel"/>
</Label>
<AttributeDefinition
attributeId="inspectionNeeded"/>
<Placement insertKey="after" insertId="folder"/>
Tip: For more information and examples refer to the comments in the property
file.
Where:
– <create or update> defines whether part attributes are copied over at the
creation of the equivalent link for the downstream part (create), or when
the equivalent link of the downstream part is updated (update). If
<create> is used alone there is no synchronization between the upstream
and downstream parts. To create a scenario where upstream and
downstream parts are synchronized update the property to include both
<create> and <update> options.
– <WTPart or WTPartMaster> defines whether the copied attributes are
from the upstream iteration of the part (WTPart) or from the upstream
part master (WTPartMaster).
– <attribute> is the attribute to be copied over during BOM transformation.
Tip: To keep the copied attributes specific to a product update the property
must include the product library container. For example:
<Property name="com.ptc.windchill.mpml.copyOver.<create or
update>.wt.part.WTPartMaster.<PDMLinkProduct.Product1>"
default="WCTYPE|wt.part.<WTPart or WTPartMaster>~MBA|
defaultUnit"/>
Where:
– <PDMLinkProduct.Product1> is the name of the product container.
Note: To copy over multiple soft attributes, or attributes that are sub-classes of
other attributes, you must include the full path to the attributes you want to copy
over, using the delimiter specified in the following property:
<Property name="com.ptc.windchill.mpml.copyOverDelimeter"
default=","/>
3. Search for:
<Option cardinality="singleton" requestor="WCTYPE|
wt.associativity.EquivalenceLink"
serviceClass="com.ptc.windchill.mpml.MPMCopyOverEquivalenceLink
Delegate"/>
4. Substitute
"com.ptc.windchill.mpml.MPMCopyOverEquivalenceLinkDelegate" with
the name of the class that implements the new behavior. Or modify the class
itself to change the behavior.
Topic Page
Customizing Index Search Capabilities ............................................................21-2
Customizing Indexing Behavior........................................................................21-6
Windchill Client Architecture Search Customization .....................................21-11
Search Elements and Associated JSPs ............................................................21-17
21-1
Customizing Index Search Capabilities
There is support for creating a new Customized search application with Index.
The Indexed-Search webject queries the indexing engine for the indexed content
of Windchill objects if Index Search is installed. It accepts a 'keyword' String as
input and returns XML formatted results (see below). It includes the ufid(obid),
the object class, a rank, and a teaser for every associated contentItem for that
object. It also may include one or more spelling suggestions.
<wc:COLLECTION xmlns:wc="http://www.ptc.com/infoengine/1.0">
- <wt.fc.WTObject NAME="output" TYPE="Unknown" STATUS="0">
<wc:INSTANCE />
- <wc:INSTANCE>
<obid>VR:wt.doc.WTDocument:22052</obid>
<class>wt.doc.WTDocument</class>
<teaser>Basketball rules Basics Goal is to shoot the ball into a
basket (10' high) to score points. A basic shot counts as 2 points,
and shots from the three point line count as 3 points and free
throws count as 1 point.</teaser>
<rank>1997</rank>
<contentItem>OR:wt.content.ApplicationData:22059|1898|Basketball
rules Basics Goal is to shoot the ball into a basket (10' high) to
score points. A basic shot counts as 2 points, and shots from the
three point line count as 3 points and free throws count as 1
point.</contentItem>
</wc:INSTANCE>
<wc:INSTANCE>
<suggest>wrong</suggest>
</wc:INSTANCE>
</wt.fc.WTObject>
</wc:COLLECTION>
SESSION_ID
Session identifier with all tasks
TYPE
Specifies the set of Windchill Business Types to constrain the search. This
would be wt.part.WTPart, wt.doc.WTDocument, etc.
WHERE
If specified, the indexing tool will attempt to filter results based on the
whereClause.
KEYWORD
Specifies a query expression identifying the keyword string to be sent to
Index Search.
LIBRARIES
Specifies the set of Index Search libraries (collections) to search for the
keyword.
These two are optional parameters. The default values are "sortBy" and "sorted",
respectively. If the parameters are not present, or if the default values are used, no
sorting is done.
To specify the fields to sort by, set the SORTBY parameter value to any of the
fields defined for the particular library.
The default library (collection) provided in Windchill is wblib; the list of fields
(for example, "name", "number", "title") is shown in the IndexSearch
You can give multiple fields and their corresponding sort orders by space
separated values. For example:
<ie:param name="SORTBY" data="name number"/>
<ie:param name="SORTED" data="asc"/>
This would sort the results first on name and then number.
For further information on the Indexed-Search webject, see the Windchill Adapter
Guide.
IndexSearch Fields
In addition to the full text index of object metadata and content files, text can be
indexed into specific IndexSearch fields. When text is indexed into fields, it is
possible to restrict, or filter, query responses by entering search terms in data
fields, such as title, number, date, and so on. These queries can be used in
combination with a full text query or used alone to limit the types of documents
returned. Windchill provides a Index Search Profile configured with the fields in
the table below.
If you want a library to contain additional fields, you must add those fields to the
profile before data is indexed into the library. Refer to the Index Profile Features
Management section of the InStream Configuration Guide for further information
on setting up library fields. After the fields have been defined for the library, you
can write a custom InstreamIndexDelegate subclass to populate the new fields
with the appropriate data, or you can simply append them onto the following
property in wt.properties:
wt.index.IndexFields=
name,lifeCycleState,description,number,title,containerReference,modifyTimestamp
Notice that some attributes are indexed automatically and cannot be overridden.
These methods do nothing in the base class, so anything added will be additional
functionality for the indexing system. There are examples below on how to call
specific methods to write customized fields, or specify additional metadata on an
indexed object.
To put your custom InstreamIndexDelegate into action, you must update the
service.properties file to reflect this change. Following is the default
InstreamIndexDelegate entry:
# #####################################################
# The wt.index.IndexServiceDelegate service.
# ###########################################################
wt.services/svc/default/wt.index.IndexServiceDelegate/null/
wt.index.Indexable/0=wt.index.InstreamIndexDelegate/duplicate
As part of the changes introduced in 8.0, the ability to subclass the delegate by
type is no longer supported. However, this functionality can easily be reproduced
by logic in a customer IndexServiceDelegate. Also, the ability to define a
delegate for a single library is no longer supported either, but fields that are not
defined in a particular library are ignored, so sending additional information to
IndexSearch is not an issue.
For this example, assume that you have a custom InstreamIndexDelegate named
InstreamSubClassIndexDelegate that you want to use to index. If you want to
override the default InstreamIndexDelegate you must add the following line to
service.properties:
wt.services/svc/default/wt.index.IndexServiceDelegate
/null/wt.index.Indexable/0=
wt.index.InstreamSubClassIndexDelegate/duplicate
(Note that you should actually enter only one line; the indentation shown here
indicates a continuation of the preceding line, necessary for presentation of lines
within the book.)
import wt.index.InstreamIndexDelegate;
import wt.index.IndexingException;
import wt.util.WTException;
/**
* This method can be used to provide customized fields to be
indexed
* in your Indexing engine.
**/
********EXAMPLE**********
Objective
Scenario A: Allow user to add customized attribute to Criteria drop down
Scenario B: Allow user to add new action for given type to search result table
Scenario C: Allow user to add new customized type to search item picker
Background
• Scenario A - An out-of-the-box user can search on all the modeled attributes
as well as soft attributes for given Object Tyep. User can not see attributes
that are added by modeling the Object in Rational Rose.
• Scenario B - The site-defined preference,
/com/ptc/windchill/enterprise/search/allSearchTypes,determines the list of
types that are to be included when a user searches across "all" Object types.
This is the same list that a user can choose from within the Object Type picker
for the Customize link on the Search page, and the Search For link onthe
Advanced Search page
• Scenario C - The allSearchTypes preference defines a base list of types; out-
of-the-box searching rules include all soft types defined from one of these
types. It does not, however, include any modeled subclasses. Any new
modeled object type should be defined in the allSearchTypes preference to
make it available for searches.
Scope/Applicability/Assumptions
• Scenario A - New attributes are added to item by Rational Rose modeling.
• Scenario B - New actions are defined
• Scenario C - New item or object type is modeled in Rational Rose
Intended Outcome
In above case user has added new attribute Real and Real _Units which are added
by rose modeling.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Basic development involving HTML forms, JSP, XML, Java
After adding the new type you should set the property
com.ptc.windchill.search.refreshTypesFromProperties to "true" in wt.properties.
Sample Code
Search element and their associated JSP for Simple Search Page
Chapter Page
Customizing Business Logic............................................................................. 22-1
Customizing Change Management ................................................................... 23-1
Customizing Life Cycle Administration ........................................................... 24-1
Customizing Workflow Administration............................................................ 25-1
Customizing Workgroup Managers .................................................................. 26-1
Customizing Windchill Visualization Services ................................................ 27-1
Report Generation ............................................................................................. 28-1
Customizing Event Audits ................................................................................ 29-1
Customizing Communication Tools ................................................................. 30-1
22
Customizing Business Logic
Topic Page
Identified Business Classes ..............................................................................22-2
Customizing Iteration and Version Identifiers ................................................22-17
Customizing a Bill of Materials ......................................................................22-19
Customizing User Preferences ........................................................................22-24
Writing a Servlet Helper to Use URLFactory Functionality...........................22-30
Updating a Master Through an Iteration .........................................................22-32
22-1
Identified Business Classes
Identity Attributes
Identity attributes are the attributes of an object that, as a whole, distinguish it to
the user from other objects. The designer of a class must decide which attributes
compose its identity. For example, a SubFolder is identified by its name and its
parent folder. A WTPart’s identity attributes include number and name. For
classes that are uniquely identified, at least one of the identity attributes of the
class must have a uniqueness constraint in order to distinguish between different
instances of the class.
Overview
The following figure illustrates the IdentityService.
Identified
When a class implements the Identified or UniquelyIdentified interface, the
identity attributes of the class must be modeled in a special way. Also, a single
method on the Identified interface -- getIdentificationObject -- must be
implemented. UniquelyIdentified has no methods to implement.
wt.change2.WTChangeRequest2 is used to illustrate the step-by-step instructions.
See the class diagram named "request" in the wt.change2 package of the Rose
model for reference.
1. Add a public constructor that has arguments for each user-assigned identity
attribute.
WTChangeRequest2 has a constructor that has a single argument for the name
attribute. Number is the other identity attribute but, because it is system-
assigned, it does not need to be an argument of the constructor. In the
initialize method that is called from the generated factory method for this
constructor, the name attribute is initialized. Sequential system-assigned
attributes, like numbers, should not be initialized in the constructor, but
instead in the PersistenceManager PRE_STORE event processing right before
the object is saved. This greatly improves the odds that elements in the
sequence are not lost if the create action is aborted by the user. That is,
system-assigned attributes are initialized only when it is certain that an object
will be persisted.
2. Set the WriteAccess model property to "protected" for all identity attributes.
IdentificationObject
Throughout these instructions, the example of wt.folder.SubFolderLinkIdentity is
used to illustrate each step. See the class diagram named "Identification" in the
wt.folder package of the Rose model for reference.
1. Model a subclass of IdentificationObject in the same package.
wt.folder.SubFolderLinkIdentity extends IdentificationObject. Notice that the
subclass of IdentificationObject is in the same package as the class that
implements Identified, namely SubFolderLink. This is a requirement because
SubFolderLinkIdentity must call protected setter methods on SubFolderLink
to change the value of its identity attributes.
setParentFolderReference((ObjectReference)link.
getRoleAObjectRef());
setSubFolderName(link.getFoldered().getName());
//##end initialize%356993D30199.body
}
((SubFolderLink)obj).
setRoleAObjectRef(getParentFolderReference());
//##end setToObject%356993A900B2s.body
}
This String is a combination of the parent folder and subfolder name. This
indicates the uniqueness constraint on SubFolderLink is that no two
subfolders in a given parent folder can have the same name.
The preceding figure illustrates the general case. Consider a specific example,
WTPartMaster. WTPartMaster has two identity attributes: name and number.
Number must be unique across all subclasses of WTPartMaster, so we must
implement a SemanticKey. WTPartMasterKey extends SemanticKey and
WTPartMasterIdentity extends IdentificationObject. The implementation of
WTPartMasterIdentity.getKeyClassName returns "wt.part.WTPartMasterKey"
and WTPartMasterIdentity.getIdentity returns the part number. So, whenever a
WTPartMaster is saved, the value of the part number is stored in the
WTPartMasterKey table. Any subclass of WTPartMaster also stores its number in
the same SemanticKey table, WTPartMasterKey. Because there is a uniqueness
constraint on the key attribute of the WTPartMasterKey class, unique part
numbers are guaranteed across WTPartMaster and all its subclasses.
When using the CompositeUnique property, only two unique indexes can
currently be specified in the model. Additional attributes can be added to the
index in the subclass by adding them after the "+".
((WTChangeRequest2)obj).setNumber(number);
//##end setToObject%356DC85D038A.body
}
Iteration identifiers are by default specified as being an integer series where this
series contains whole numbers from a minimum to a maximum value. The default
minimum is one (1) and the default maximum is the largest possible 32-bit
positive integer value as defined by 2**31-1 (2,147,483,647). There is also a
default specification of the delta between adjacent numbers, which is one (1)
meaning that, if given 10, the next incremented integer value would be 11 by
default.
Version identifiers are by default specified as being a harvard series. A harvard
series is one that is made up of subseries and is typically depicted as a stream of
values delimited by a dot (for example, 1.1, 1.3.5, 1.2.1.1, and so on). Version
identifiers must be specified as some sort of multilevel series where the harvard
series is currently the only option. This is done to represent both in-lined versions
and branched versions in one identifier that forms a version tree. In turn, the
harvard series’ subseries are by default specified as being multi character series at
level one and then, because there are no other levels specified, the default from
there on is what was specified before for all levels. In this case, it would be multi
character series for all levels. If level two was specified as an integer series then,
starting at the beginning, every two levels would alternate from a multi character
to integer series up to the specified depth as seen below.
wt.series.HarvardSeries.depth=16
wt.series.HarvardSeries.level.1=wt.series.MulticharacterSeries
wt.series.HarvardSeries.level.2=wt.series.IntegerSeries
Overview
A Bill of Materials (BOM) is a product structure report that identifies the items
required to assemble a product. Currently, the BOM report includes only items
from a part structure. Two types of BOMs are supported.
• A BOM Hierarchy report shows the quantity and unit attributes of the "usage"
associations and visually indicates the hierarchical levels.
• A Parts List report is a list of all of the components (that is, parts that do not
use other parts) in the part structure hierarchy. It uses information in the
"usage" associations to determine the quantity of each component. Basically,
it answers the question "When a part assembly is completely disassembled,
what parts and how many of each do I have?".
Both of these reports are defined to be generated as an HTML page optimized for
printing from a Web browser. Both the BOM generation and formatting can be
customized as needed.
A BOM report is generated using a template processor. The actual BOM
information is generated entirely by Visitor objects. These objects are a means of
specifying a "callback" operation for each node in a "tree" data structure. For
example, a part structure contains Part objects linked together through the "uses"
relationship. Starting from a top-level part, the entire part structure is traversed
and a "visit" method is called on the Visitor object passing the current part object
and the related usage information. This method can be overridden to provide
customized BOM computation and formatting.
Customization
The remainder of this section describes an example of a BOM that is provided
out-of-the-box with Windchill. Understanding this example provides a basis for
implementing other BOM customizations. There are two types of customization
for a BOM. BOM computation refers to the work that is done on each item as the
structure is traversed. Windchill provides two types of BOM computation:
hierarchy and parts list. The second customization is for formatting the output that
is displayed to the user. This formatting is dependent on the type of information
displayed.
The visit method performs a basic output of the part identity and usage
information. The preVisitWrite() and postVisitWrite() calls are significant
because they allow for formatting customization.
public boolean visit( Persistable fromNode, Link link,
Persistable toNode, int level,
boolean previouslyVisited ) throws WTException {
preVisitWrite(level);
postVisitWrite(level);
return true;
}
out.print("<H");
out.print(a_level + 1);
out.print('>');
out.print("</H");
out.print(a_level + 1);
out.print('>');
out.flush();
}
}
Soft attributes on parts are displayed in the BOM reports automatically using the
table view, but soft attributes on part usage link cannot be displayed
automatically. The soft attributes on the part usage link are shown in the list of
available columns, but to get the actual value to display, the corresponding report
JSP file needs to be customized to indicate the specific soft attributes from the part
usage link to display.
As an example, if a soft attribute "LinkName" was added to part usage link, the
values of that attribute can be displayed by
1. Set up a custom table view with that column as one of the selected columns.
2. Add the following to the describeTable section of the JSP:
<describeColumn id="IBA|LinkName" targetObject="link" <any
other settings for the column> />
After the customization is complete, you need only specify that the new
customized class should be used when the BOM is generated. By default, the
BOM template processors use the application services mechanism to instantiate a
Visitor object that is used to generate the BOM. The service can be replaced by
changing the appropriate entry in the services.properties file. Change the
following entry in the file:
to:
wt.services/svc/default/wt.part.BOMHierarchyVisitor/print/
wt.fc.WTObject/0=wt.part.HtmlHeadingHierarchyVisitor/duplicate
Note the use of the "print" value in the "visitor" key in the service entry.
Currently, the Windchill client code displays a BOM designed for printing within
an HTML page and therefore uses the value "print". This key value is obtained
from the URL parameters by the BOM template processor. If the client were
customized to provide other types of BOM formats (by specifying different values
in the URL), this key could be used for generating different formats. For example,
an additional client function could be added for viewing a BOM with embedded
graphics. A new value "graphic" could be used that is associated with a
customized Visitor that will generate appropriate graphic output. Both types of
formatting would then be available to the user.
Preference Definition
The preference definition contains all of the static information about a preference
which is stored in the database. This definition contains a default value and the
constraint (as in the IBA constraints) for what is allowed as a value instance. The
preference API returns this default value if a preference value (in the form of a
preference instance) is not located in the database. Display information used in the
Preference Manager UI is also defined in the preference definition as resource
bundle entries. The static information in the preference definition includes the
following:
• Name
• Default Value
• Display Name
• Display Description
• Display Long Description
• Visibility (Hidden, Site, Org, Container, User, and User Only)
• The value handler for processing the preference values
Visibility
The preference definition contains a visibility flag to show who can see a given
preference in the Preference Manager.
• HIDDEN- preference would be one that is not visible in the Preference
Manager.
• SITE - preference is on that is visible only to the Site Administrator.
• ORGANIZATION - preference is one that is visible to the Site and Org
Administrators. Each Org could have a separate instance of the value tied to
that Org.
• CONTAINER - preference is one that would be visible to the Site and Org
Administrators and the Container Manager.
• USER - preference is one that would be visible at all levels.
• USER_ONLY - preference is one that is settable only at the user level.
Preference Instance
The individual values are set within the preference instance. The preference
instance ties the chosen context; Site, organization container, application
container (such as a projects, programs, products, or libraries) or user to the
preference definition with the value set for the context. If a preference instance is
not found in a request for a preference, then the default value defined in the
preference definition is returned.
Preference Category
The category is just a means of grouping preferences in the tree structure of the
Preference Manager. An individual preference definition is contained within a
preference category. A preference category can be contained within another
category. This allows for a hierarchical view of the preferences. The preference
category has no impact on the actual operation of the system, but is used in the
administration of the preferences.
Preference Client
The client was added for UWGM to set preference values by Authoring
Applications like AutoCAD, CATIA V5, etc. The default client name if not
specified is “WINCHILL”, defined by the constant
wt.preference.PreferenceClient.WINDCHILL_CLIENT_NAME.
Preference values can be set for each application context, or for an individual user,
unless the preference value is locked at a higher level. For example, if a
preference is not locked at the organization level, then it may have one value at
the organization level, but individual products or projects within that organization
could each specify a different value. Similarly, if a preference is not locked at an
organization level, but is available at the user level, then individual users could
each set different values for that preference.
Preferences can be locked at any level above the individual user. If a preference is
locked, then the value cannot be changed for those lower levels. A site or
organization administrator can choose to delete all values for a particular
preference that may be set at levels below the current context, usually prior to
locking the preference.
If a preference is not explicitly set for a particular application context, then the
value for that preference is inherited from the level above. For example:
• •If a preference is not set for a particular product or project, then the value set
for that preference at the organization level is used.
• •If the preference is not set at the organization level, then the value set for that
preference at the site level is used.
• •If no preference is set at any level, then the default value defined for that
preference is used.
The above method will return the value at the user context if it exists, otherwise
the value set at the container context and so on up the preference hierarchy. Other
single preference value methods in the wt.preference package include:
public Object getValue( String definitionName, String clientName );
The first method retrieves value at the Site context, while the second method
retrieves the value at the Organization context and if it does not exist, then the
inherited value at the Site is returned.
Multiple preference values can be retrieved at the same time. This is more
efficient in database calls:
public Map<String, Object> getValues(WTContainerRef containerRef,
Collection<String> definitionNames, Collection<String>
categoryNames, String clientName, WTUser user)
Example:
Map<String,Object> preferenceMap = null;
definitionNames.add("PREFERENCE_DEFINITION_1");
definitionNames.add("PREFERENCE_DEFINITION_2");
definitionNames.add("PREFERENCE_DEFINITION_3");
definitionNames.add("PREFERENCE_DEFINITION_4");
Adding Preferences
New preference definitions and categories are added using the LoadFromFile
utility to load an XML based load file. This can be run with the following
command:
An example XML preference load file which loads various preference definitions
and preference categories is the Windchill/loadfiles/preference.foundation.xml
load file.
Example Preference Definition:
<?xml version="1.0"?><!DOCTYPE NmLoader SYSTEM "standardX10.dtd">
<NmLoader>
<csvPreferenceDefinition
handler="wt.preference.LoadPreference.createPreferenceDefinition">
<csvname>PREFERENCE_DEFINITION_1</csvname>
<csvvisibility>USER</csvvisibility>
<csvcategoryName>UNASSIGNED</csvcategoryName>
<csvdisplayName>com...PrefsRB:MYPREF_NAME</csvdisplayName>
<csvdescription>com...PrefsRB:MYPREF_SHORT_DESC</csvdescription
>
<csvlongDescription>com...PrefsRB:MYPREF_DESC</csvlongDescripti
on>
<csvdefaultValue>false</csvdefaultValue>
<csvhandler>wt.preference.handler.BooleanPreferenceValueHandler
:
</csvhandler>
</csvPreferenceDefinition>
<csvLinkPreferenceClientDefinition
handler="wt.preference.LoadPreference.setClientDefinitionLink">
<csvname>PREFERENCE_DEFINITION_1</csvname>
<csvclientName>WINDCHILL</csvclientName>
</csvLinkPreferenceClientDefinition>
</NmLoader>
wt.preference.preferenceResource:Unassigned
<csvname>UNASSIGNED</csvname>
<csvparentName></csvparentName>
<csvdisplayName>wt.preference.preferenceResource:Unassigned
</csvdisplayName>
<csvdescription></csvdescription>
</csvPreferenceCategory>
//////////////////////////////////////////////////////////////////////
// This file is intended to give an example of how the URLFactory
// and GatewayServletHelper may be used within
// the JSP programming environment. To run this file, simply
// place the file in the /Windchill/codebase/wtcore/jsp directory.
// Extra whitespace as been left in for clarity and ease of reading.
///////////////////////////////////////////////////////////////////////
%>
<% /*** The WTContextBean is a JavaBean for use in Java Server Pages or
Servlets that wish to use Windchill Java client or server APIs ***/ %>
<% /*** The URLFactory is a JavaBean for use in the generation of HREFs used in
Windchill JSP clients ***/ %>
<jsp:useBean id="url_factory" class="wt.httpgw.URLFactory" scope="request" >
<%
url_factory.setRequestURL(request.getScheme(),request.getHeader("HOST"),
request.getRequestURI());
%></jsp:useBean>
<%
// The response header for the output stream should be set to UTF-8
response.setContentType("text/html; charset=UTF-8");
// Below we also set the content type in the @page tag, since some
// servlet engines
%><%@ page import="wt.httpgw.*,java.util.HashMap" contentType="text/html;
charset=UTF-8" %>
<%
// Here we want to generate a link to the Windchill home page through
// the default authenticated gateway. For this we will utilize the
// wt.httpgw.GatewayServletHelper class to generate a HREF which
// from the current URLFactory will generate a link to this site.
// %>
<BR>
<A HREF="<%=
wt.httpgw.GatewayServletHelper.buildAuthenticatedHREF( url_factory )
%>">Windchill Home</A>
<BR>
<% // Perhaps you would like a link to your personal cabinet. In order to
// do this, you must generate a link through the authenticated gateway
// with a class/method and arguments to invoke like below
<%
// For optimization, any links generated in the fashion described above could be
// generated reusing the HashMap and Strings already created. The Setup.jsp file
// located in codebase/wtcore/jsp/wt/portal/Setup.jsp does just this in the
// generation of the links thus reducing the overhead in String/HashMap object
// creation.
//
// In the FORM below we use the URLFactory to generate a link to the resource
// wtcore/jsp/sample.jsp. See the Javadoc for method prototypes. The URLFactory
// is smart enough to see how it is currently configured and return a String link
// which should work within the current environment. For the example below, since
// we are running the file from /WEB-APP/wtcore/jsp the link will generate simply
// "sample.jsp". Optionally we could have called
// url_factory.getHREF("wtcore/jsp/sample.jsp",request.getQueryString() ) if we
// wished to retain the current Query string.
%>
<FORM ACTION="<%= url_factory.getHREF("wtcore/jsp/sample.jsp") %>" METHOD="POST">
<INPUT TYPE="text" NAME="Sample_Text" VALUE="<%= prev_value %>">
<INPUT TYPE="submit">
</FORM>
Introduction
The master-iteration documentation (described the Windchill Design Patterns
chapter on page 35-1) specifies that the Mastered and Iterated classes work
together closely. A class that implements Mastered (henceforth called the master)
contains all the version-independent information, whereas the Iterated class
(henceforth called the iteration) contains the incremental change that an object
undergoes. When applying the master-iteration pattern, it is important to consider
whether the master and iteration will be treated as a single logical object or as two
distinct objects. Specifically, consider whether a client needs to know that a
document is actually composed of an iteration and a master.
The Windchill reference implementations WTPart and WTDocument define the
master attributes on the iteration as derived attributes, thus hiding the existence of
the master from clients. For both WTPart and WTDocument, the only attributes
Topic Page
Change Management Delegates ........................................................................23-2
23-1
Change Management Delegates
The wt.change2 package has several delegates defined to allow customization.
The following is an overview to help you know where to start.
ChooseLifeCycleDelegate
ChooseLifeCycleDelegate is used within StandardChangeService2 by calling the
protected method chooseLifeCycle. In the chooseLifeCycle method, the delegate
is obtained from the Change2DelegateFactory. The chooseLifeCycle method is
not called if the change object is already persisted, because it would already have
a life cycle set. In the chooseLifeCycle method, the delegate mechanism is used
only if a life cycle has not yet been set.
// In any of the saveChange... methods, such as saveChangeRequest:
If changeItem is not persistent {
ChangeServiceHelper2.service.chooseLifeCycle (changeItem);
}
// In chooseLifeCycle
if changeItem has no lifecycle {
Set the lifecycle using the delegate;
}
ChooseFolderDelegate
ChooseFolderDelegate is used within StandardChangeService2. It is obtained
from the Change2DelegateFactory.
The Windchill vision of change management is that change issues, requests and
orders should be visible in folders so that a user can easily look for issues (or
suggestions), requests (issues that are being addressed), and orders (changes that
have been made). The investigations, proposals, analysis activities, and change
activities are tightly tied to other objects and they are not visible in folders.
Because these related objects need the same access control and other attributes of
their related object, which is in a folder, Windchill puts them in the same domain
as the related object that is in a folder. The ChooseFolderDelegate assigns one
ChangeItem to a folder/cabinet based on the folder/cabinet of another
ChangeItem.
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
DisplayIdentificationDelegate
DisplayIdentificationDelegate is used within StandardChangeService2. It is
obtained from the Change2DelegateFactory. For further information, see the
section on implementing new display identification delegates in the identity
service description in the System Generation chapter on page 32-1.
Topic Page
Customizing the Display of Life Cycle Information.........................................24-2
Defining Customized Life Cycle Transitions....................................................24-3
Setting Up a Customized State-Based Versioning Scheme ..............................24-3
24-1
Customizing the Display of Life Cycle Information
The way life cycle state information is displayed, particularly in life cycle-
managed object properties pages, can be customized by setting configurable
components in the wt.lifecycle.lifecycleResource*.java files. You can set values
for the following entries:
STATES_SEPARATOR
When displaying a string of states, this value is the separator between each of
the states listed. Default is " - ".
CURRENT_STATE_BEGIN
When displaying a string of states, this value is the notation that a particular
state is the current state. Default is "<B>".
CURRENT_STATE_END
When displaying a string of states, this value is the notation that a particular
state is the current state. Default is "</B>".
DROPPED_STATE_BEGIN
This entry notes that the current state (usually dropped) is not found in the list
of current states. Default is " [".
DROPPED_STATE_END
This entry notes that the current state (usually dropped) is not found in the list
of current states. Default is "] ".
IS_AT_GATE
This value is used to indicate that Awaiting Promotion = true. Default is
"Yes".
IS_NOT_AT_GATE
This value is used to indicate that Awaiting Promotion = false. Default is
"No".
LABEL_BEGIN
This value is used when displaying any of the StateProcessor labels. Default is
"<B>".
LABEL_END
This value is used when displaying any of the StateProcessor labels. Default is
": </B>".
STATE_LIST_BEGIN
When the list of states is provided along with other information, this entry
differentiates the State list from other information in the display. Default is
"(".
STATE_LIST_END
When the list of states is provided along with other information, this entry
differentiates the State list from other information in the display. Default is
")".
HISTORY_LABEL
This entry is used when displaying a link to the Life Cycle History page.
Default is "History".
2. Build the runtime resource bundles for the customized packages by entering
the following command from a windchill shell:
ResourceBuild wt.lifecycle.TransitionRB
The new transition will be added to the transitions that are available when you
create or update life cycles using the Life Cycle Administrator.
The new transition can be accessed programatically. You can invoke the
navigate() method to find the valid transitions between states using that new
transition, such as in the following code snippet:
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("MY_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
MY_REJECT transitions.
Finally, rebuild the jars in a Windchill shell with the following command:
<Windchill>\ant\bin\ant –f <Windchill>\codebase\makejar.xml
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"?>Basic<?loc-end?>
</Arg>
Note: <If this rule is defined at Site or Organization level, object initialisation
rules defined at context level may need to be disabled.
Topic Page
Customizing Workflow HTML Templates .......................................................25-2
Customizing Change Management Workflow Process Templates ...................25-6
Customizing Promotion Request Workflow Processes...................................25-13
Customizing Workflow Events on an Object..................................................25-17
Customizing Workflow Task Pages ................................................................25-19
Refine and Review Workflow Transitions Best Practice................................25-27
25-1
Customizing Workflow HTML Templates
This section describes how to customize HTML templates for workflow activities.
Following are possible ways you could use this capability:
• To change the layout of the standard workflow activity property pages to add
customer logos and so forth.
• To add read-only displays of process variables.
• To integrate information (attributes, icon, associations, and so on) of the
primary business object of the workflow.
• To display a summary of process variables, for example, the voting and
comments of different reviewers as the basis for a promote decision.
The functionality to perform all of these customizations is available through
existing Windchill scripts, as seen in the standard Windchill HTML client. As a
result, you can make these customizations without programming Java (possibly
only one resource bundle change), but only editing HTML and some entries in a
Windchill properties file.
For both an overview and detailed information about customizing HTML clients,
see the Customizing HTML Clients Using the Windchill JSP Framework chapter
on page 11-1. This section discusses the HTML client only as it applies to
workflow.
The string "Customized Task Name" is displayed in the drop-down list and
must be localized. The string "CustomTask" is the value of the action
argument in the URL requests of the HTML page for a workflow activity of
that type.
2. Add or modify the appropriate entries in the service.properties and
htmltemplate.properties files. If you add an entry in the resource bundle, you
must add a line similar to the following in the service.properties file:
wt.services/svc/default/wt.enterprise.TemplateProcessor/
CustomTask/java.lang.Object/
0=wt.workflow.worklist.WfTaskProcessor/
duplicate
This script does not print any HTML code but switches the
ContextObject of the TemplateProcessor. This means the scripts that
follow this script in the HTML page can generate information about
the new ContextObject (for example, attribute names and values of
the primaryBusinessObject or a table of associated objects).
– From wt.enterprise.BasicTemplateProcessor:
• To create a link to another dynamically generated page, use the
following script (see the Javadoc for further information):
objectActionLink action="action" [label="label"]
labelPropertyName="labelPropertyName" ]
Most of the time you will have to add entries in the properties files to
create new actions and new related HTML template files that hold
only a part of an HTML page (for example, a single table).
Introduction
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
Template Robot
The following table explains the details of this figure; the numbers in the table
correspond to numbers in the figure.
1a) This conditional router checks if the change issue is already associated to a
change request. If so, the workflow continues to the conditional at 3a; otherwise,
it proceeds to the sync robot at 1b.
1b) The Sync on Request Association robot waits until the event
ISSUE_FORMALIZED is emitted for the primaryBusinessObject (the change
issue), signaling the change issue has been attached to a change request. The
workflow then continues to the conditional at 2a and the conditional at 3a
simultaneously.
2a) This conditional router checks if 3a) This conditional router checks the
the change issue has been immediately state of the associated change request.
disassociated with the change request. If it is in state Completed, the
If so, the workflow cycles back to 1a; workflow continues to 3b (the end of
otherwise, it continues to the sync the process). If it is in state Cancelled,
robot at 2b. the workflow loops back to a point
near the beginning of the process.
Otherwise, the workflow continues to
the sync robot at 3b.
Template Robot
Before Release 5.1, the expression logic performed the following actions:
1. Determine the parent change request by navigating one or two levels of
associations based on the change object:
– For a change investigation or change proposal, navigate the
ResearchedBy association.
– For a change order, navigate the AddressedBy2 association.
– For an analysis activity, first navigate the DetailedBy association to
obtain a change investigation or change proposal, then navigate the
ResearchedBy association.
– For a change activity, first navigate the IncludedIn2 association to obtain
a change order, then navigate the AddressedBy2 association.
2. Determine the current life cycle state of the change request.
3. Determine the current value stored in the Complexity attribute (for Sync on
Request Submit only).
This robot has been replaced with a conditional router followed by the sync
robot. The new robot, which has been changed to an object event
synchronization robot, is shown in the following figure.
The object is the new change request process variable just described. The
event is STATE CHANGE in each case. 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. (In both
figures, the parentChangeRequest variable is assumed to be initialized
already.)
• The expression in the object event synchronization robot and conditional has
been changed to use the workflow variable parentChangeRequest directly,
rather than access the database repeatedly to determine the parent change
request.
Template Robot
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.
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";
}
The promoteTargets API also takes care of the process of unlocking the targets
before promoting them. This kind of an unlocking mechanism should also be
incorporated in the customized workflow.
3. Rebuild the client JARs (see Rebuilding Client JARs in the Managing
Customizations chapter on page 5-18).
4. Clear the Java Plug-in cache on your client machines.
5. Restart the Method Server.
6. Use the Workflow Process Editor to design a workflow template with a
Synchronization robot, as shown below:
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.
A customer may also choose to customize the task form template (i.e., the
customized JSP) to only display individual components of the PBO. For example,
they might want to include just the top attributes, affected data, affected end
items, attachments, attribute detail (including soft or modeled), or related change
items.
The tag tablePageLink can be used to display one or more tables that are defined
together in one custom jsp. The parameter path is the jsp that will be included. The
tablePageLink tag can only be used once on a page to render one jsp file and it
cannot be used on the same page as infoPageLink.
<tags:tablePageLink
path="/netmarkets/jsp/change/affectedEndItemsTable.jsp"/>
Reassignment
<workItem:promotionObjects/>
<Option
serviceClass="com.ptc.windchill.enterprise.change2.handler.Defa
ultAutomateCreateChangeNoticeHadler"
selector="DefaultHandler" requestor="null"
cardinality="duplicate"/>
</Service>
Once the new template is uploaded, a new JSP file gets created in the
codebase/netmarkets/jsp/customtemplates folder. The name of the new JSP will
be generated based off a mapping mechanism, using the Container, PBO class,
Activity Type, and JSP template name.
The JSP name will be generated using the mapping mechanism as follows:
<ContainerName>_<PBOType>_<ActivityType>_<Template Name>.jsp
Note: It's assumed that at least the out-of-the-box templates are present in the
system. If no template is found due to deletion of templates then an exception will
be raised.
Objective
Sometimes there is a need to set all the Resulting Items into a new state that
cannot be checked out or modified so everyone has a consistent view of the
Resulting data.
Scope/Applicability/Assumptions
• It is assumed that you are familar with change management concepts such as
resulting data.
• It is assumed that your Windchill system supports Refine and Review
workflow transitions.
• It is assumed that you have administrator level aceess to the Workflow and
Life Cycle applications.
Intended Outcome
To understand how to customize the workflow to use the Refine and Review
transitions.
Solution
Prerequisite knowledge
To follow this process you need to have an understanding of the following:
• Knowledge of creating and modifying a workflow
Caution: If you copy and paste the transition code out from this document
and directly into Windchill, the quotes will be invalid characters for the java
compiler. It is suggested that you paste it into a Notepad first, copy it from
Notepad, then paste into the Windchill Expression box.
Changing the Life Cycle of Part to handle Refine and Review transitions
Note: In the followingscenario, the part is using the Two Phase Development
Life cycle instead of the default one.
Topic Page
Customizing and Administering Pro/ENGINEER Wildfire .............................26-2
26-1
Customizing and Administering Pro/ENGINEER Wildfire
See the "Customizing and Administering Pro/ENGINEER Wildfire" chapter in
the Using Pro/ENGINEER Wildfire with Windchill guide for information.
This chapter presents customization and administration information and
recommendations for using Pro/ENGINEER Wildfire integrated with Windchill
PDMLink and Windchill ProjectLink. The primary audience is Pro/ENGINEER
and Windchill system administrators; however, much of the information can be
useful to end users as well.
The topics presented include Pro/ENGINEER configuration information
(environment variables and config.pro options) that applies to the interaction with
Windchill, and Windchill server-side preferences, as well as specific information
on parameter mapping, parameter customization, customizing object naming,
automated part creation, supporting custom parts, and customizing the user
interface. In addition, recommendations for system configuration and
performance tuning are offered.
The final section lists and describes Windchill preferences that are especially
relevant to the interaction with Pro/ENGINEER.
Topic Page
Custom Publishing ............................................................................................27-2
27-1
Custom Publishing
Objective
You want to initiate publishing from another product area or from custom code.
You may also want to define alternative inputs to the creation of a representation
such as naming, descriptions, or configuration specifications to an OOTB
publishing mechanism (i.e. check-in driven and scheduled publishing).
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
Solution Elements
For more details on this method and it’s parameters, see the JavaDoc in
<Windchill>\codebase\wt\clients\library\api\index.html.
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”,
“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,
You have a WTDocument with several pieces of content. For example, doc1.doc,
doc2.doc and doc3.doc are all content of your WTDocument and you only wish to
publish doc3.doc (by default all docs would be published).
String objRef = ObjectReference.newObjectRefer-
ence(mydoc).toString();
PublisherAction pa =
new PublisherAction(PublisherAction.DOCUMENTFILE, “doc3.doc”);
Publisher pub = new Publisher();
boolean result = pub.doPublish(true, true, objRef, (Config-
Spec)null,
(ConfigSpec)null, null, null,
Publisher.NONE, pa.toString(), 0);
findRepresentable
To simplify the concept discussed above, there is a method called
findRepresentable in com.ptc.wvs.common.ui.VisualizationHelper. This method
allows you to pass in a Representable and always get back the right Representable
in the case where actively associated parts are involved. In the case where there
If you have custom code that is dealing with Representables, it is a good practice
to use this method so you can be sure to have the right Representable that is
associated to the Representations. Also, note that if you pass in a Persistable that
is not a Representable, the method will return null. You must have an instance of
VisualizationHelper to use this method. For example:
VisualizationHelper vizHelper = new VisualizationHelper();
Representable repable = vizHelper.findRepresentable(d);
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)
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);
Note: All three of the above methods make use of the findRepresentable method,
so you do not need to worry about actively associated parts when calling it.
Additionally, if the Persistable passed in is not a Representable, null will be
returned.
You can use whatever method name you want, but it is important that the method
be public, static, return a WTList and accept no arguments.
Then add the following to your wvs.properties.xconf file (edit as needed):
<Property default="MyCustomJob" name="myJob.description"/>
<Property default="ext.wvs.CustomJobs" name=" myJob.class"/>
<Property default="myCustomJob" name=" myJob.method"/>
<Property default="true" name=" myJob.enableOnContainers"/>
<Property default="myJob" name="schedulejobs<N>"/>
while (true) {
while (qr.hasMoreElements()) {
doc = (Representable)((Object[])qr.nextElement())[0];
wtl.add(doc);
}
offset += qr.size();
if (offset >= total) break;
return wtl;
}
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);
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;
This is the same example used in the Custom Schedule Job Fundamentals section
(see page 27-8), but notice the use of the doPublish method shown in bold. This
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.
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.getLifeCycleState() != State.INWORK) {
return Boolean.TRUE;
}
return Boolean.FALSE;
}
You can use whatever name you want in place of docFilterMethod. Make sure the
class that contains your custom method is accessible in the Windchill codebase
(i.e. ext.wvs.MyFilterMethods). Notice that this method differs from the
EPMDocument filter method signature by including ContentItem as a parameter.
This method is called for each ContentItem associated to the WTDocument on
check-in. It is also called for uploads. For example if you had a WTDocument
with .doc file as primary content and a .xls file as secondary content, this method
would be called twice; once with each content item (pending a worker was
associated to both types of content).
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/docFilterMethod"
name="publish.service.filterdocumentpublishmethod"/>
Once you make the change use the xconfmanager to propagate the changes to
wvs.properties.
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);
This is the same example used in the Filter Publishing for EPMDocument Check-
in section (see page 27-12), 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 the Procedure – Invoking Publishing from Custom Code/Workflow
(see page 27-3) for see other useful ways to use the doPublish method.
You can use whatever name you want in place of filterMethod. Make sure the
class that contains your custom method is accessible in the Windchill codebase
(i.e. ext.wvs.MyFilterMethods). This method includes a publishFromDB
parameter. This Boolean will come in as Boolean.TRUE if the publish is being
invoked for data stored in Windchill, i.e. content of an EPMDocument or
WTDocument object. The value will come in as Boolean.FALSE if the publish is
for data not stored in Windchill, i.e. local data converted from the file system or
data from the clipboard. You can use the value of publishFromDB to have your
custom code handle the two cases specifically if you wish.
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/filterMethod"
name="publish.service.filterpublishmethod"/>
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.
Note: In the example above that the second line states that if we have publishing
requested for data from Windchill stored data, just return Boolean.TRUE. For
example if the request was to publish the primary content of a WTDocument we
just want to 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 (f.k.a. CAD 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.
Additional Resources
• Java Development: http://java.sun.com
• The "Visualization Services" chapter in the Windchill Business
Administrator’s Guide
• wvs.properties.xconf file in your <Windchill>\codebase directory.
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.
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
build on the capabilities of the Windchill foundation and use HTML, CSS, XML,
and XSL technologies, you should also be familiar with these areas to use the
tools most effectively for customization.
Topic Page
Overview ...........................................................................................................28-2
Basic Report Example .......................................................................................28-2
Import and Export of Report Templates..........................................................28-11
Customization Details .....................................................................................28-15
Cognos Presentation Customization................................................................28-38
Reporting Info*Engine Task Data Source Customization ..............................28-44
Report Loading................................................................................................28-50
ReportTemplate Data Source Customization ..................................................28-59
Reporting Input Page Customization ..............................................................28-63
Report Localization Customization.................................................................28-68
Report Selection List Customization...............................................................28-74
28-1
Overview
Reports are generated by applying presentation information to query result data.
Queries are built using the Windchill Query Builder tool and stored as a report
template business object in Windchill. When a report template query is executed,
it operates against the current database and produces output in the form of Java
objects or XML.
Reports are generated from XML output by applying presentation transformations
defined by XSLT (Extensible Stylesheet Transformation) stylesheets. The
combination of XML and XSLT allows for a separation between data collection
and formatting, thus facilitating separate customization of each. When defining
report template objects, you can select from out-of-the-box XSLT formats or
specify custom XSLT stylesheets to meet your formatting needs.
Query
The following steps show how to create the initial query for the report:
1. Create a new report template object and specify the query using the Query
Builder user interface, as follows. (For detailed usage instructions, use the
Query Builder online help.)
a. From Report Manager, click the New button. The Query Builder interface
appears (see figure below).
b. To add classes for the query, click the Add button on the From tab. Select
the Foldered and Cabinet classes. These classes will be used as the basis
for the query.
e. Add criteria for filtering the results to only a single cabinet. On the
Criteria tab, set the following values, as shown in the following figure:
Field Value
Alias Cabinet
Attribute Name
Operator =
Value System
csvname Required.
csvdescription Optional.
The following example exports all report template objects in the Windchill PDM,
default 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
container 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
XSLT Customization
As mentioned earlier, reports are produced by applying XSLT stylesheet
transformations to XML query results. This includes all the out-of-the-box
formats. XSLT stylesheets are capable of producing not only any HTML layout
but also any other XML or text format.
XSLT stylesheets are based on the concepts of templates and rules. Most XSLT
stylesheets are largely composed of XML or HTML tags and text that are static;
that is, included verbatim in the output. The remainder of the stylesheet is then
composed of rules for computing the dynamic portion of the output from the input
XML. Depending on the mix of templates and rules, the nature of XSLT
customization can vary from simple HTML authoring to pure programming. For
the definitive specification on XSLT, refer to the W3C XSLT specification,
currently available at the following URL:2
http://www.w3.org/TR/xslt
For additional information about XSLT, refer to the What is XSLT? link and the
Resources area currently available at the following URL:3
http://www.xml.com
1. If you have difficulty with this URL, try the site URL www.w3.org.
2. If you have difficulty with this URL, try the site URL www.w3.org.
3. If you have difficulty with this URL, try the site URL www.xslinfo.com.
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"
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.
• 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.
4. If you have difficulty with this URL, try the site URL www.xml.com.
5. If you have difficulty with this URL, try the site URL www.w3.org.
6. 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.
Element Description
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.
Customizing Macros
Customizing macros uses the standard Windchill application services delegation
mechanism (for further information, see the Customizing service.properties topic
in the Developing Server Logic chapter on page 36-24). This customization
example creates a new macro to automatically compute a cutoff time. A new
query is created that uses this macro and generates a report containing objects that
have been modified within the last three days.
Note that this example assumes you are familiar with Rational Rose and
Windchill code generation, and have completed the previous customization
examples.
1. Create a new implementation of the MacroExpressionProcessor interface
using Rational Rose and Windchill code generation 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. Generate the code for this class.
3. Create a new report query that uses the new macro by performing the
following steps:
a. Open the existing Foldered query and save it as a new query, for example,
FolderedModified.
b. Remove the criteria based on cabinet name.
c. Add criteria. On the Criteria tab, set the following values as shown in the
following table:
Field Value
Class Foldered
Attribute thePersistInfo.modifyStamp
Operator >
Note that the time cutoff macro now appears in the drop-down list.
d. Save the query.
4. Execute the report.
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
This is necessary only if the class does not implement the NetFactor interface, but
does have subclasses that implement the Persistable interface.
Objective
You want to create a Cognos report that queries data from an existing Windchill
Data Source.
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>/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 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
the Reporting Data Source customization best practice documentation in the
ReportTemplate Data Source Customization on page 28-59 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.
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 Windchill UI to locate <MyReport> and select the “Delete”
action.
Note: The Reports tab table supports a multiple row delete action if the Reports
tab 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.
Cognos Reports are subject to the Cognos server’s access control policies. When
Cognos is deployed as part of WBR, the integration does not alter Cognos default
access control permissions, users, or groups apart from configuring Cognos to
share Windchill LDAP for authentication. Further alteration to the access control
permissions, users, or groups in Cognos must be done via Cognos’ tools, i.e. via
their UI or API which is described in the Cognos documentation. For a good
Sample Code
Related Websites
• http://support.cognos.com/support
Objective
You want to create a new Windchill programmatic data retrieval task to use in a
report.
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 Info*Engine User’s Guide 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.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
• Info*Engine User’s Guide
Solution Elements
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
typeId=com.ptc.windchill.enterprise.report.ReportTask
6. Create and Install a package for <MyTask>. See “Advanced User Topics >
Packages” in the Info*Engine User’s Guide.
-->
Customization Points
Limitations
The typeId in the .delegateInfo file maps to the SOAP class and the task file name
maps to the SOAP method within that class. Both of these names should only
contain characters valid for Java identifiers. In addition, the methods must all be
unique for a given class. For a given typeId, each task name must be unique.
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
Related Websites
• http://support.cognos.com/support
Objective
You want to load reporting objects into a Windchill Business Reporting (WBR)
system.
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>/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 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>.
Assume you will load a new Windchill Report object, <MyReport>, and it will
use the <MyReportTemplate> 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.
For WBR integration, you must also have access rights to update the reporting
meta model.
Solution
Construct and execute load files for Reporting objects.
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
• ReportManager User Interface
• Windchill Data Loading
Solution Elements
4. Update the Cognos model to recognize this new Data Source. Launch
JConsole from installed Windchill shortcuts.
5. Make connection to Tomcat JVM instance.
6. Select reporting management bean from the MBeans tab, “Tree > com.ptc >
WebAppContexts > <WindchillInstanceName> > Monitors >
ReportingSystem”.
7. From the Operations tab, click “updateModel”.
8. Verify that the Data Source exists in Cognos. Login to Cognos using the
<WBRHomeURL> and launch “Report Studio”.
9. Find <MyTask> Data Source under “Windchill > Report Tasks >
com.ptc.windchill.enterprise.report.ReportTask” in the “Insertable Objects”
window under the “Source” tab.
<csvreportTemplateName><MyReportTemplate></csvreportTemplateNam
e>
<csvreportTemplateContainerPath/>
</csvCreateReport>
</NmLoader>
3. Verify the Report exists in Windchill in the Reports tab of the Site context.
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 28-44
• ReportTemplate Data Source Customization on page 28-59
Related Websites
• http://support.cognos.com/support
Objective
You want to create a new Windchill data query to use in a Report.
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 ReportManager utility. This applet 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 ReportManager and Query Builder to construct a ReportTemplate Data
Source.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
Solution Elements
Customization Points
Limitations
None.
Sample Code
Packaged Samples
A demo ReportTemplate Data Source object, PartList, is available. It can be
loaded using the following command:
windchill wt.load.LoadFromFile –d
<WindchillHome>/loadXMLFiles/DemoReports.xml –CONT_PATH /
Note that if these objects were already loaded, exceptions may occur when
running this command. The PartList ReportTemplate object is a simple query for
Parts that returns two columns with part number information. It will be created at
the Site context and will be available in Cognos after executing the update model
operation.
Related Websites
• http://support.cognos.com/support
Objective
You want to provide a parameter input page for the reports in your Windchill
Business Reporting (WBR) system.
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>/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 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.
Intended Outcome
The end result of this solution is the use of your custom input when executing a
report.
Solution
Construct and specify a custom input page for reports.
Solution Elements
<MyInputPage> JSP File The custom JSP page for specifying report
input parameter values.
<MyReport> Windchill Report Windchill Object The Windchill object that is displayed to end
users in the Windchill User Interface. It acts
as a proxy to a corresponding Cognos Report
object.
%><fmt:requestEncoding value="UTF-8"
/>
<html>
<head>
<title>My Input Page</title>
</head>
<body>
<h2>My Input Page</h2>
<form>
<%
String paramName = “param1”;
String defaultInputValue = “default1”;
<%
String hiddenParamName = “param2”;
String hiddenValue = “value2”;
%>
%>
</form>
</body>
</html>
Customization Points
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://support.cognos.com/support
Objective
You want to provide localized versions of your custom reports in your Windchill
Business Reporting (WBR) system.
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 (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 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
• ReportManager User Interface
Solution Elements
<MyTaskResource> Resource Bundle Info The resource bundle info file used to
Properties File localize Info*Engine task text items.
<MyReportTemplateResource Resource Bundle Info The resource bundle info file used to
> Properties File localize ReportTemplate text items.
<MyReport> Windchill Report Windchill Object The Windchill object that 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 file used to
Properties File localize Report text items.
<MyCognosReport> Cognos Cognos Object The Cognos object for a report that
Report contains the definition of the query and
specifies the presentation formatting.
<MyCognosReportResource> Resource Bundle Info The resource bundle info file used to
Properties File localize Cognos Report static text.
3. Update the Cognos model to incorporate the localized text. Launch JConsole
from installed Windchill shortcuts. Make connection to Tomcat JVM
instance. Select reporting management bean from the MBeans tab, "Tree >
com.ptc > WebAppContexts > <WindchillInstanceName> > Monitors >
ReportingSystem". From the Operations tab, click "updateModel".
Customization Points
7. Verify the report in Cognos. Refresh the "Public Folders > Windchill" folder
and the <MyCognosReport> object should be listed. Use the "Run with
options…" action to run the report. Try setting different client locales to
ensure that the static text is translated properly.
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.cognos.com/support
Scope/Applicability/Assumptions
The processes described in this section are applicable to the following report
types:
• Part
• Part Configuration
• Part Instance
This section describes the process for customizing the report selection list. It does
not include information on how to author a report or load a report into a third party
reporting system. For any custom reports, it is assumed that they have been
authored and that a JSP file exists for each custom report that needs to be hooked
up to the existing report list.
It is assumed that the person doing the customization has access to make the
updated to <WindchillCodebase> directory.
Solution
The following section describes the process of customizing the report selection
list in detail.
Solution Elements
partReportResource.rbInfo Resource bundle Optional. Used to define the localized names for reports
Runtime location:
<Windchill>/codebase/com/ptc/windchill/enterprise/part/
structure
Overview
1. Implement and compile the custom delegate that defines the list of reports,
including any custom reports to be displayed in the ‘Related Reports drop
down’ in the Product Structure Browser.
2. Author the Custom Report JSP file (and other related artifacts) corresponding
to the custom report(s) into the <Windchill>/codebase.
3. Add and build the localization entries for the custom report(s) and build the
localization resources.
4. Register the custom delegate by replacing the out of the box with the custom
delegate.
5. Restart Windchill for your changes to take effect.
Sample Code: Adding a new custom part report at the end of the existing part report list
If you want to add a new custom part report at the end of the existing (out of the
box) part report list. Assume that the new custom report has a JSP file
netmarkets/jsp/part/custom/myCustomReport.jsp.
import
com.ptc.windchill.enterprise.part.structure.partReportResource
Sample Code: Remove existing part reports from the report list
The following example shows the code to remove some of the existing part
reports from the list.
import
com.ptc.windchill.enterprise.part.structure.AbstractProductStructu
reReportListDelegate
// Single-Level BOM
super.generateSingleLevelBOM();
In case your reports require the access to the encoded configuration specification,
you can use
ProductStructureReportSelectorHelper.decodeConfigSpec(encodedConfigSpec)
to decode the configuration specification. ProductStructureReportSelectorHelper
Example <customReport>.jsp
This is an example of how to access the JSP parameters.
<%
String hostName = request.getRemoteHost();
String sessionId = session.getId();
String oid = (String)request.getParameter("oid") ;
String applyCSToTop = (String)request.getParameter("applyCSToTop")
;
String part = (String)request.getParameter("part") ;
String encodedConfigSpec = (String)request.getParameter(
"encodedConfigSpec" );
String applyDCSToUnresolved =
(String)request.getParameter("applyDCSToUnresolved") ;
%>
sessionId D180CB2067B751629C8BA557A355D11D
oid wt.part.WTPart:78035
part VR:wt.part.WTPart:68117
applyCSToTop false
applyDCSToUnresolved false
encodedConfigSpec rO0ABXNyABh3dC5wYXJ0LldUUGFydENvbmZpZ1NwZWMAAAAAA
AAAAQQAAHhyABR3dC5lbnRlcnByaXNlLlNpbXBsZQAAAAAAAAA
BBAAAeHIADnd0LmZjLldUT2JqZWN0AAAAAAAAAAEEAAB4cLWF
MlThpvDmcNMGeSFFACwBAQ ….
• For a Part Instance report, execute the following command from within
<Windchill> directory in Windchill shell:
xconfmanager -s
wt.services/svc/default/com.ptc.windchill.enterprise.part.struc
ture.ProductStructureReportListDelegate/reportSelector/wt.part.
WTProductInstance2/0=<Qualified
Path>.<CustomDelegate>/duplicate -t service.properties -p
• For a Part Configuration report, execute the following command from within
<Windchill> directory in Windchill shell:
xconfmanager -s
wt.services/svc/default/com.ptc.windchill.enterprise.part.struc
ture.ProductStructureReportListDelegate/reportSelector/wt.part.
WTProductConfiguration/0=<Qualified
Path>.<CustomDelegate>/duplicate -t service.properties -p
Restart Windchill
You must restart the following for the changes to take effect:
• Apache
• Tomcat
• ServerManager
• Method Server
Topic Page
Introduction .......................................................................................................29-2
Overview of the Audit Event Framework .........................................................29-3
Capturing New Events.....................................................................................29-10
29-1
Introduction
The auditing framework provides a mechanism to enable event-based logging that
provides a historical record of who did what that caused changes in the Windchill
database. The security auditing feature also provides a mechanism to retain
historical records of security related events, such as privilege changes, team
changes, and denial of access. Security audit reporting is helpful to customers in
highly regulated industries that need to identify events that may have resulted in a
potential security breach. The following list provides possible application uses
that can be recorded:
• Who accessed the application?
• Who viewed or downloaded an object?
• Who changed this object?
• Who granted access to a specific user?
The Windchill Auditing Framework is a Windchill service that captures events
generated through normal application use, using a collection of classes and
configuration files that a customer modifies to indicate which specific events are
to be recorded in the audit log. Out-of-the-box, the auditing framework is enabled
at the global level. However, the only events that are enabled are License Usage
Reporting and Organization Usage. Any other specific events that you want
recorded in the audit log must be enabled on an individual basis.
eventLabel This is the localized value of the external label for the event
represented by this AuditRecord. It is translated into the
server's locale when the AuditRecord is recorded in the
database
userOrgName Organization the current user belongs to at the time the event
was emitted.
userName Name of the user that is the current principal when the event
happened.
IPAddress IP address of the client machine used when the event was
emitted.
cageCode Cage code of the object that is the target of the event.
masterID Identifier of the master of the object that is the target of the
event.
appContainerID Identifier of the application container that owns the object that
is the target of the event.
appContainerName Name of the application container that owns the object that is
the target of the event.
folderPath Folder path of the object that is the target of the event.
domainPath Domain path of the object that is the target of the event.
lifecycleState Lifecycle state of the object that is the target of the event.
The information contained in the AuditRecord class is sufficient for most events.
In certain situations, however, the Windchill Auditing Framework is required to
capture additional information specific to the event generated. The event-specific
information is stored in an event-specific table and is managed by an event-
specific object.
For example, when a user is added to or removed from a group, it is important to
note which user is involved and not just that the group membership was modified.
The class ModifyGroupEventInfo holds the additional information as a reference
to the user being added or removed. If multiple users were added or removed in a
The <ConfigEntry> element identifies the events to be audited for a specific class.
The class attribute identifies a fully qualified class name to be audited. Within the
<ConfigEntry> element there are additional elements defining the specific events
being monitored for the class and which audit recorder persists the event
information. Originally, these sub-elements were specific to an event type;
PersistenceManagerEventEntry for PersistenceManagerEvent,
AccessControlEventEntry for AccessControlEvent, etc. New in X-05, the
KeyedEventEntry element allows the event class to be explicitly defined and
should be used exclusively going forward.
ConfigEntry dtd (part 2)
<!ELEMENT ConfigEntry (KeyedEventEntry | WIPEventEntry |
WfEngineEventEntry |
PersistenceManagerEventEntry | ActionItemEventEntry |
ProjectServiceEventEntry | AccessControlEventEntry |
ProjectManagementEventEntry | RenameEventEntry |
CustomEventEntry | GroupEventEntry | ForumEventEntry |
VCEventEntry)*>
<!ATTLIST ConfigEntry
class CDATA #REQUIRED
enabled (true | false) #REQUIRED
>
<!ELEMENT KeyedEventEntry EMPTY>
<!ATTLIST KeyedEventEntry
eventKey CDATA #REQUIRED
enabled (true | false) #REQUIRED
handler CDATA "wt.audit.configaudit.DefaultAuditEventRecorder">
try {
trx.start();
WTCollection auditRecordCol =
super.persistMultiObjectEvent(anEvent);
int numObjs = auditRecordCol.size();
<event_info_class> eventInfo =
<event_info_class>.new<event_info_class>();
eventInfoCol.add(eventInfo);
}
PersistentObjectManager.getPom().insert(eventInfoCol, null,
null);
trx.commit();
trx = null;
return recordCol;
}
catch (WTPropertyVetoException pve) {
throw new WTException (pve);
}
finally {
if(trx != null) {
trx.rollback();
}
try {
trx.start();
<event_info_class> eventInfo =
<event_info_class>.new<event_info_class>();
PersistentObjectManager.getPom().insert(eventInfo, null,
null);
}
trx.commit();
trx = null;
return record;
}
catch (WTPropertyVetoException pve) {
throw new WTException(pve);
}
finally {
if (trx != null) {
trx.rollback();
}
}
}
Windchill provides tools that enable your team to communicate and collaborate
effectively, such as support for meetings, subscriptions, and discussion forums.
This chapter describes how to customize communication tools, where such
customization is supported in Windchill.
Topic Page
Customizing Meetings.......................................................................................30-2
Customizing Action Items (Windchill ProjectLink Only) ................................30-3
30-1
Customizing Meetings
Windchill PDMLink, and Windchill ProjectLink provide the ability to customize
the authentication scheme used for Webex meetings. A delegate object,
implementing the WebexUserInfoDelegate interface, is used to create the account
name and password. To perform this type of customization, you need to write a
class that implements the interface WebexUserInfoDelegate and substitute that for
the default delegate provided out of the box with Windchill.
1. Write your customized WebexUserInfoDelegate.
Write a class that implements the wt.meeting.WebexUserInfoDelegate
interface. See your installed Javadoc for details on the
WebexUserInfoDelegate API. Any class that implements this interface must
conform with all Webex requirements. For example, names, email addresses,
and passwords must conform to the Webex requirements listed in the Webex
API documentation. If storing any information is required to make this work,
that is also the responsibility of the implementor.
2. Include the compiled class in the Windchill codebase in the same way that
you include other customizations.
3. To make Windchill actually use the new delegate, modify the service delegate
mapping according to the procedure described in the Customizing
service.properties topic in the Developing Server Logic chapter on page
36-24. In service.properties, the out of the box entry for
WebexUserInfoDelegate is as follows:
wt.services/svc/default/wt.meeting.WebexUserInfoDelegate/default/java.lang.Object/0
=wt.meeting.DefaultWebexUserInfoDelegate/singleton
Note: When searching for action items on the Advanced Search page, all
attributes are available, including those not currently exposed in the user interface.
Date No Date
Percent No %
Quantity No Integer
Time No hh:mm
enabled="true"
order="40"
required="false"
resourceBundle="wt.meeting.actionitem.actionitemModelRB"
displayType="textBox"
internalName="Comments"
type="java.lang.String"/>
Chapter Page
Windchill Services ............................................................................... 31-1
System Generation ............................................................................... 32-1
Customizing Modeled Elements .......................................................... 33-1
Enumerated Types................................................................................ 34-1
Windchill Design Patterns ................................................................... 35-1
Developing Server Logic ..................................................................... 36-1
The Enterprise Layer............................................................................ 37-1
Persistence Management...................................................................... 38-1
Advanced Query Capabilities .............................................................. 39-1
Internationalization and Localization................................................... 40-1
Customizing Archive, Purge, and Restore ........................................... 41-1
Import Export Framework ................................................................... 42-1
Evolvable Classes ................................................................................ 43-1
Creating Large Objects (LOBs) ........................................................... 44-1
Customizing Data Formats................................................................... 45-1
31
Windchill Services
Topic Page
Windchill Packages ...........................................................................................31-2
Engineering Factor Services..............................................................................31-2
31-1
Windchill Packages
Windchill’s functionality — that is, its services and utilities — is generally
separated into Java packages. These packages are available in the wt and com.ptc
directories within the Windchill codebase directory. You can use these packages
as you build new applications and customize existing applications. Model files are
provided so you can extend some of the classes in the models and then generate
code for them. This section lists a subset of the packages available for use in
customizations and gives an overview of their functionality. Some of the packages
are described in further detail in other chapters of this guide, or in the
accompanying Javadoc for the package.
access
Functionality for access control; used to define access policies (that is, define
rules for what principals have access to what information). See the wt.access
class entry in your installed Windchill Javadoc for more information.
admin
Functionality to create administrative domains and policies. See the wt.admin
class entry in your installed Windchill Javadoc for more information.
content
Functionality for handling content data (attaching files and URLs to content
holders, such as documents and change objects) and associating business
information metadata (such as the author) with content. See the wt.content
class entry in your installed Windchill Javadoc for more information.
content replication
Functionality for increasing the speed at which users can access data. Data is
stored on more rapidly accessible external vaults known as replica vaults.
Base packages cannot be extended or modified in any way. Additional
information about content replication is discussed in the Windchill System
Administrator’s Guide.
effectivity
Functionality to assert that a PDM object is effective under certain conditions.
See the wt.eff and wt.effectivy class entry in your installed Windchill Javadoc
for more information.
epm
The engineering service (wt.epm package) provides functionality to create
and manage CAD model related objects. See the wt.epm and subpackages
entry in your installed Windchill Javadoc for more information.
federation
The federation service (wt.federation package) provides functionality to
create and manage proxy objects of remote systems and perform utility
functions supporting the federation system. See the wt.federation class entry
in your installed Windchill Javadoc for more information.
EPMDocument Model
An EPMDocument can represent a component or an assembly, using other
EPMDocuments as components. (This concept is described further in the section
on Handling Model Structure later in this section.)
As shown in the following model, EPMDocument implements a number of
Windchill interfaces that allow it to be used in various Windchill services:
RevisionControlled
Allows the EPMDocument to be checked in and out
Baselineable
Allows the EPMDocument to be stored in a baseline
FormatContentHolder
Allows the EPMDocument to have content
DocumentVersion
Allows the EPMDocument to be treated as a document by the Windchill
Explorer
EPMDocument Model
Creating an EPMDocument
An EPMDocument must be created via the factory method newEPMDocument:
EPMDocument doc = EPMDocument.newEPMDocument (
<number >, <name >, <EPMAuthoringAppType authoring App >,
<EPMDocumentType docType>, <CADName>);
The number of the document must be unique within the Windchill database. The
ownerApplication is an EnumeratedType indicating the application that intends to
manage changes to the document. The concept of owner application is no 2 set via
a call to EPMContextHelper.setApplication (EPMApplicationType appType),
where EPMApplicationType is an EnumeratedType. Set the "current application"
for use by checking code. This value is cached on the client-side, but is also sent
(via the EPMContextManager) to the server-side SessionContext.
Once setApplication () has been called, all objects created will be tagged with the
specified application. For Pro/ENGINEER authored CADDocuments, CADName
needs to be specified. EPM Services ensure that CADName is unique in a
Windchill database.
EPMDependencyLink
When an EPMDocument represents an assembly, it uses other EPMDocuments
via EPMMemberLinks. It can also reference other EPMDocuments via
EPMReferenceLinks; reference links are non-structural, but are used to include
objects that provide scenery, or constraints.
Both EPMMemberLinks and EPMReferenceLinks are types of
EPMDependencyLink (shown in the following figure), which is used to represent
the concept of one EPMDocument depending on another.
EPMMemberLink
The EPMMemberLink represents the use of one model by another. It includes
data such as quantity and positioning, as shown in the following figure.
EPMReferenceLink
The EPMReferenceLink represents reference to an object by a model. While an
EPMMemberLink can use only another EPMDocument, any Iterated object can
be referred to (for example, a specification in Microsoft Word). The relationship
between an EPMDocument containing a drawing and the EPMDocument
containing the model is represented using an EPMReferenceLink. The direction
of this link should be such that the drawing describes the model. The model never
describes the drawing.
Build Model
When you have finished modeling, the next step is system generation. Using
Windchill extensions to Rose’s original functionality, Windchill generation tools
generate Java code, Info files containing class metadata used by the runtime
environment, and database DDL from the models you create. This chapter
describes how to use the system generation tool and how the classes you model in
UML (in Rose) correspond to the code that is generated.
Topic Page
Overview of System Generation .......................................................................32-2
How Rose UML Maps to Java Classes .............................................................32-3
Implicit Persistable Associations Stored with Foreign ID References............32-21
Extending the EnumeratedType class .............................................................32-36
How Rose UML Maps to Info Objects ...........................................................32-39
How Rose UML Maps to Database Schema ...................................................32-41
How Rose UML Maps to Localizable Resource Info Files ............................32-47
Using the Windchill System Generation Tool ................................................32-50
Using Windchill System Generation in a Build Environment ........................32-54
Deploying Modeled Customizations ...............................................................32-60
32-1
Overview of System Generation
The figure below shows the system generation process.
Using the models in the Rational Rose repository, the Windchill export tool
produces mData files. The system generation tools then use the mData files to
produce Java code, Info files (metadata used by the runtime environment), and
database schema. mData files have a non-proprietary file format so that, in the
future, different modeling tools can be used without rewriting portions of the
system generation tool.
The following sections describe how the Rose UML is mapped to each of the
types of output (Java code, Info files, and database schema). The final section of
this chapter describes how to run the system generation tool.
Model of a Class
Package Statement
The package statement corresponds to the Rose UML package that owns the class.
For example,
// Example of a generated package statement
package example;
Import Statements
Java import statements are generated based on references made to other classes
through the following model elements:
• Class and Interfaces inherited by the class.
• Dependencies modeled for the class.
• Non-Persistable Association types.
• Attribute types declared by the class.
• Argument type s specified by the methods of the class.
• Return value types specified by the methods of the class.
• Exceptions thrown by the methods of the class.
For example,
// Examples of a generated import statements
import example.MyAddress;
import example.MySize;
import java.lang.String;
import java.sql.Date;
import java.util.Vector;
import wt.fc.Item;
import wt.pds.PersistentRetrieveIfc;
import wt.pds.PersistentStoreIfc;
import wt.pom.DatastoreException;
import wt.util.WTException;
import wt.util.WTPropertyVetoException;
The negative side-effect to this change is that imports previously generated from
model dependencies will not be automatically removed when the dependency is
removed from the model. For instance, if a class changed from using Vector to
using List, both classes would continue to be imported. Developers need to purge
unused import statements as they notice them.
Class Documentation
Any documentation that is entered in Rose will be generated into the class in the
form of Javadoc style comments. For example,
//##begin MyItem% [ ]34F19D1A00B3.doc preserve=no
/**
* An example class to demonstrate system generation
*
* @version 1.0
**/
//##end MyItem% [ ]34F19D1A00B3.doc
Class Declaration
A class is declared as modeled and will extend and implement all of the classes
that were modeled as having a generalization relationship. If a class is modeled to
extend a class that was not modeled as Extendable, via the Windchill
SupportedAPI property, the generator will not allow it to be generated until that
modeled generalization is removed.The class can be modeled as concrete,
abstract, or as an interface. For example,
// Example of a class declaration
public class MyItem extends Item implements Externalizable{
The RESOURCE constant identifies the resource bundle the class is to use for
localizable messages.
The CLASSNAME constant provides an easily accessible, programmatic
reference to the name of the class.
The rest of the class body contains the generated results of elements modeled as
features of the class and as relationships between classes. These include
operations, attributes, associations, and generalizations. The details of these will
be covered in subsequent sections.
• Java Properties
– Generate should be set to False if the system generation tools should
ignore this modeled class.
– CodeGenerationName specifies the name of the class that will be
generated. Leave it blank to have the generated name be the same as the
name of the modeled class.
– Serializable indicates if the generated class will implement the
Serializable or Externalizable interface. Default evaluates to
Externalizable, if possible; otherwise, Serializable. Externalizable
(basic), can be used to generate simple Externalization support that does
not include support for reading old versions.For a class that will have
instances serialized into BLOB columns in the database, set the property
to Evolvable. (For further information, see appendix D, Evolvable
Classes.) To have the class implement neither interface, set the property
to None.
– PrimitiveType indicates which primitive value-type a class can be
decomposed into.
– StaticInitBeforeFields indicates whether the static initializer will be
placed before the field declarations.
– GenAttributeLabels indicates whether label constants will be generated
for the modeled attributes and roles of the class. If True, they will be
Model of Operations
return null;
//##end operation1% [ ]34F19DCB01D0.body
}
}
Operations modeled in Rose are mapped as Java methods of the generated class.
For operations that are not modeled as abstract, stubs are created in the generated
class where you add your own code. All documentation, keywords, parameters,
and return types that are modeled in Rose are generated into Java classes.
Information about operations that you can specify in Rose is detailed below.
The begin and end markers that are generated into editable files denote the
sections that you can edit. These sections are preserved as is during subsequent
generations of the files.
Some sections are marked with preserve=no. This is true for all Javadoc comment
sections and some code sections, where some implementation is generated into an
editable file. The "no" value for preserve indicates that the section is a generated
default, which you may choose to edit. If you do edit any of these sections, you
must change the preserve value from "no" to "yes"; otherwise, it will not be
preserved.
If MyItem were an interface, only the operation declaration would be generated
into MyItem, because a Java interface can contain no implementation. To the
degree possible, the implementation aspects of interface operations will be
Attribute Implementation
The external Java representation of a class attribute modeled in Rose consists of a
getter operation, a setter operation, and an identifying label. The export visibility
of the getter and setter operations is based on the export visibility of the modeled
attribute in Rose.
The internal Java implementation of the class attribute is always a private field.
This field is accessed strictly through getter and setter operations. Encapsulating
the attribute as a private field provides several benefits:
• The class controls the integrity of the attribute by monitoring changes to the
attribute.
• The class can support subscribe/notify functionality that allows listeners to
monitor the state of the attribute.
• Access through getter and setter operations provides the opportunity to
synchronize access to the attribute.
The following model shows the class MyItem, with attributes a1, a2, and a3,
which extends the class Item.
Model of Attributes
Field Declarations
All attributes modeled in Rose are implemented as private fields of the Java class.
For example,
// Examples of attribute declarations
private String a1;
private Date a2;
private Xyz a3;
The accessor methods to these attributes are public or protected, depending on the
export control as defined in the model. Examples of accessor methods follow.
Accessor Methods
Public and protected accessor methods are generated in the Java class. For
example,
// Example of a "getter" method
public String getA1() {
return a1;
}
// Example of a "setter" method
public void setA1( String theA1 )
throws WTPropertyVetoException {
a1 = theA1;
}
Accessor methods are code-generated from the attributes modeled on the business
class in the Rose model. They need not be modeled on classes in the UML model.
These accessor methods follow the Java beans naming convention. Attributes that
were modeled as public get public accessor methods. Attributes that were
modeled as protected get protected accessor methods.
The system generation tool generates accessors that enforce attribute validation
based on attribute properties specified in the model.
If the constrain property (a Rose specification) is set to true for an attribute
modeled in Rose, the setter method is declared to throw a
wt.util.WTPropertyVetoException, which is derived from
java.beans.PropertyVetoException. This exception is thrown if the setter method
has determined that a value being set in the attribute is invalid. Developers can
change the default accessor methods by writing code in the preserve region.
• Java Properties
– Final should be set to True if the resulting field should be final.
– Transient should be set to True if the resulting field should be transient.
– Volatile should be set to True if the resulting field should be volatile.
– Persistent should be set to True if the field that holds the value will be
persisted to the database.
– GenerateAccessors should be set to False if no accessors are to be
generated.
– Constrain should be set to True if the resulting setter method should
declare that it throws a WTPropertyVetoException.
– GetExceptions specifies exceptions that will be declared as thrown by
the generated getter.
– SetExceptions specifies exceptions that will be declared as thrown by the
generated setter.
– BeforeStaticInitializer should be set to True if field declaration should
be placed prior to the static initializer.
• Datastore Properties
– ColumnName is the class attribute to column name mapping. Default is
the attribute name.
– ColumnType is used to indicate the relational storage type for the value-
type. By default a mapping, based on the attribute type, will be used.
– Index specifies whether an index is created for this attribute.
– Unique specifies whether a unique index is created for this attribute.
– Updatable specifies whether the column can be updated using standard
persistence mechanisms.
• Oracle Properties
– TableSpaceName is the tablespace to use for storage option of the table.
– TableSize indicates the relative size required for the objects that will be
stored (the actual storage values are mapped from the size via property
file settings).
Non-Persistable Associations
The following model shows associations with non-persistable objects
(MyAddress and NameValue).
return (MyItem)getRoleAObject();
}
setRoleAObject( theMyItem );
}
// two-arg factory for link classes
public static LinkA newLinkA( MyItem theMyItem,
Yours theYours )
throws WTException {
The link class is generated for LinkC, just as it was for LinkA, in the preceding
example. In addition, the following code is generated in the class that plays the
role opposite the role that has a cardinality of one.
public class OneMore implements Persistable, Externalizable {
In this case, since the association is persisted via a foreign id in the table for
OneMore rather than in a separate link table, the OneMore class will hold a
reference to myItem and will get myItemReference accessors generated. In
addition to the getter and setter that are generated for the reference, a convenience
getter is generated for the myItem object.
Although these additional accessors are created for developer convenience, the
LinkC class that is generated for the association can be operated on in the same
manner as a link class that is stored in a separate link table. This provides a
common API for manipulating links, regardless of how the database storage is
implemented.
The example also had a derived attribute modeled for the OneMore class. The
DerivedFrom property for the attribute was defined as myItem>a1, which caused
the A1 label constant and accessors to be generated for the a1derived attribute. (If
this were a non-persistable association, the syntax for the derived attribute source
would be myItem.a1.)
Care should be taken in using this feature with persistable associations since
allowing the generation and use of a derived setter will cause a state change in a
different persistable object (myItem) which may not be obvious to the developer
who is using your class (OneMore). The generation of the setter can be turned off
while retaining the generation of the getter by setting the attribute’s WriteAccess
property to Private.
If an association has attributes associated with it, the code generator creates a Java
class that has all of the attributes for the association and the accessor. The name of
the generated Java class is the name of the attributing class.
The generated Java class extends the ObjectToObjectLink class if the attributing
class does not extend another class in the model. If the attributing class extends
another class in the model, the Java class extends that class. (The class being
extended must be a subclass of Link.)
Implementing Interfaces
In Rose, an interface is modeled as a class that has the stereotype <<Interface>>.
Factory operations
To give flexibility to the system architecture, Windchill uses a factory design
pattern for the construction of Java objects. A constructor signature is one where
the operation name matches the name of the class and has no return type. Object
constructors are modeled in Rose but are not generated directly in Java code.
Instead of constructors, Windchill generates factory operations that are used to
construct objects.
Using factory operations instead of constructors provides the opportunity to vary
the class of the returned object. When constructors are used to create an object, the
class of the returned object must match exactly the class requested. However,
when factories are used, the class of the returned object will be polymorphically
compatible with the requested class but need not match the requested class
exactly. This allows the return of objects whose class may vary depending on the
context.
This method returns the fully-qualified conceptual class name of the object.
Because the instantiated object may really be an instance of some other
implementation class, getConceptualClassname is a useful method to find the
business class in an object.
You should not use object.getClass().getName() to determine the class name for
software objects in the Windchill system because it may not return the name of the
conceptual class.
This method returns the ClassInfo instance that contains the metadata from the
installed model.
a1 = input.getString( "a1" );
a2 = input.getDate( "a2" );
a3 = (Xyz)input.getObject( "a3" );
work = (wt.tools.generation.example.MyAddress)input.readObject(
"work", work,
wt.tools.generation.example.MyAddress.class, true );
list = (Vector)input.getObject( "list" );
size = MySize.toMySize( input.getString( "size" ) );
timeline = (wt.tools.generation.example.Timeline)
input.readObject("timeline", timeline,
wt.tools.generation.example.Timeline.class, true );
}
Caution: Certain core Windchill operations may depend upon these methods
being ObjectIdentifier-based. Changes to the default implementation should be
done with care, if at all.
Externalization methods
In the generated externalization methods, all non-transient, non-static fields that
were modeled will be handled. The externalization is generated in a manner that
provides hooks for reading in previous versions of the class, unless "basic"
externalization is generated. Code generation detects when the externalizable
signature of a class changes, and changes its internal version UID accordingly.
You have the ability to take control of the externalization code, but it is not
recommended because it requires careful management of the externalizable
signature of the class.
Examples of the externalization methods follow:
// Example of a writeExternal method
public void writeExternal( ObjectOutput output )
throws IOException {
//##begin writeExternal%writeExternal.body preserve=no
output.writeLong( EXTERNALIZATION_VERSION_UID );
super.writeExternal( output );
output.writeObject( a1 );
output.writeObject( a2 );
output.writeObject( a3 );
output.writeObject( list );
if ( readSerialVersionUID == EXTERNALIZATION_VERSION_UID ) {
// if current version UID
super.readExternal( input ); //
handle super class
a1 = (String)input.readObject();
a2 = (Date)input.readObject();
a3 = (Xyz)input.readObject();
list = (Vector)input.readObject();
String size_string_value = (String)input.readObject();
try { size = (MySize)wt.fc.EnumeratedTypeUtil.toEnumeratedType(
size_string_value ); }
catch( wt.util.WTInvalidParameterException e ) { // old format
size = MySize.toMySize( size_string_value );
theOneMoreReference = (ObjectReference)input.readObject();
timeline = (Timeline)input.readObject();
work = (MyAddress)input.readObject();
else
//##end readExternal%readExternal.body
Extending EnumeratedTypes
java.lang.Double
(double) DOUBLE Types.DOUBLE
java.lang.Boolean
(boolean) BIT Types.BIT
BLOB
java.lang.String VARCHAR Types.VARCHAR INLINEBLOB
SMALLBLOB
All other types BLOB Types.BLOB INLINEBLOB
Caution: Each class must be mapped to its own unique table name. If the table
name of a customized class conflicts with that of an out-of-the-box class or
another customized class, then it must be changed using the Rose specification
table name property. Similarly, you should change the table name to avoid
matching a datastore reserved word used in your database (such as VIEW).
1. See the tools.properties file and user.properties file descriptions in the The Windchill
Development Environment chapter on page 2-13.
The first entry is the display name for the WTPart class, and the second is the
display name for partType attribute of the WTPart class. These values will only be
generated once, so that the package owner can override the default values, if
desired. For example, the value for the partType attribute could be changed as
follows:
WTPart.partType.value=Type
In addition, any of the keys described in the Resource Entry Format on page 40-9,
could be added for an element. For example, the following information could be
added for the partType attribute.
WTPart.partType.fullDisplay=Part Type
WTPart.partType.longDescription=Classification of parts
according to predefined types.
To build the runtime resource into the codebase for all the resource info files for a
particular directory, use the following command:
ResourceBuild <directory_relative_to_src>
For example:
ResourceBuild wt/part
For example:
windchill wt.util.resource.ResourceBundleUtil
wt.part.partModelRB en_GB
Registry Files
The classRegistry, descendentRegistry, and associationRegistry files are located
in the directory specified by the wt.generation.bin.dir entry in the tools properties.
The classRegistry file contains all the information the code generator needs to
create import statements for the generated Java classes. When classRegistry is
Export Model Data Rose model (.mdl and/or .cat) mData file
Generate Resource Info .mData file for target package .rbInfo files
Build Resource Bundles .rbInfo files for target package .RB.ser files
1. Accumulated during generation, but used to define the modeled relationships for the installed runtime application.
Build Sequence
The following table describes the steps and commands used in a build sequence.
1. The system generation tool will create a classRegistry if one does not exist.
2. Remember to update database table structures after generating SQL scripts that have structural changes.
Therefore, you should generate Info Objects separately from any other
generations you are performing. For example, when generating info
objects for all registered packages, do the following:
Note: To display characters entered using something other than the default
encoding, set the wt.locale.encoding property to the encoding appropriate to
your locale before running this utility.
“<package>.<Class>”
Reports for the single class specified.
“<package>.*”
Objective
You have created some modeled customizations on a development system, using
Windchill InfoModeler. You want to deploy these customizations on your
deployment system.
Background
It is recommended that you develop Windchill customizations on a development
system that is separate from your deployment system. If you create modeled
customizations (that is, using Windchill InfoModeler), follow this best practice to
deploy your generated artifacts, rather than regenerating them on the deployment
system.
For example, your deployment system may run on an operating system (such as
HP-UX) that does not support Windchill InfoModeler. To create modeled
customizations, you could use a Windows server as your development system and
run Windchill InfoModeler on that system. You would then follow this best
practice to copy the necessary generated artifacts to your deployment system.
Scope/Applicability/Assumptions
Assume you have created new modeled customization packages on your
development system.
Assume that, prior to your new customization, your development environment
included all the packages the production environment has. This best practice does
not apply if, for example:
·Your production environment is an aggregation of multiple development
environments;
·You have installed anything (such as an upgrade or module) into production that
is not also in your development environment.
Intended Outcome
Your deployment environment will again mirror your development environment,
including your new customizations.
Solution
Copy the relevant files from your development system to your deployment
system.
Prerequisite knowledge
To achieve this objective, you need to have an understanding of the following:
Solution Elements
Located in <Windchill>/codebase.
Topic Page
Customizing Column Lengths...........................................................................33-2
33-1
Customizing Column Lengths
A column length for a modeled attribute can be customized. These column lengths
are obtained through the wt.introspection package. The default column lengths are
defined in the delivered Rose models with the attribute’s UpperLimit property.
The value of this property can be overridden by placing entries in the
customizations property file for modeled packages.
To change the column length for a modeled attribute, perform the following steps:
1. Determine which customization property entry must be added.
2. Add the customization entry to the appropriate customizations property file.
3. Generate the class info objects and SQL scripts.
4. Verify the customization.
5. Create the database tables.
6. Restart the method servers if they were running during the procedure.
The following example sets the column length for the name attribute of the
wt.doc.WTDocumentMaster class to 350. The following steps describe how to
determine which customizations property file entry will contain the new column
length, and how to set the value. The customization will be made in a location
parallel with the originally modeled attribute.
The default location for these customizations is $(wt.home)\wtCustom, as defined
by the wt.generation.custom.dir entry in the tools properties1. Create this directory
if it does not already exist.
1. Determine which customization property entry must be added:
a. Obtain an info report for the class by executing the following command:
infoReport wt.doc.WTDocumentMaster
1. See the tools.properties file and user.properties file descriptions in The Windchill Development
Environment chapter on page 2-13.
ClassInfo wt.build.buildtest.SourceMaster
ClassInfo wt.federation.ProxyDocumentMaster
c. If the customized class has descendants that are concrete, their tables
must also be adjusted with the following commands (one line each):
ant -f <Windchill>\bin\tools.xml custom_column -
Dgen.input=wt.build.buildtest.SourceMaster
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
Topic Page
The EnumeratedType Class...............................................................................34-2
Creating an EnumeratedType Subclass.............................................................34-3
Editing the Resource Info for an Enumerated Type..........................................34-7
Localizing an Enumerated Type........................................................................34-9
Extending an Enumerated Type ......................................................................34-10
The Enumerated Type Customization Utility .................................................34-11
GUI Usage of an Enumerated Type ................................................................34-12
34-1
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 not
available for generic use by GUI components; they must use getDisplay().
Select the EnumeratedType property set on the Windchill tab of the Class
Specification. This property set provides just the properties that apply to
EnumeratedType classes, and changes the default values of certain properties,
such as PrimitiveType to String.
If the values are to be ordered explicitly, set the ExplicitOrder property to
True. Otherwise, the values will be ordered alphabetically at runtime, using
the locale-specific display.
1. See the tools.properties file and user.properties file descriptions in the The Windchill
Development Environment chapter on page 2-13.
Modeled constants are Static and Final. A value definition for each modeled
constant will be generated in the resource info file.
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=med
med.order=20
sm.value=sm
sm.order=10
These default values are generated only once, so that the package owner can
override the default values, if desired. If the class’s ExplicitOrder property is set
to True, the orders are controlled by the generator, and should not be edited
directly in the resource info file. If one of the constants has DefaultValue set to
True, it is controlled by the generator. For example, the value for the "sm" value
could be changed as follows:
sm.value=Small
sm.shortDescription=Small Comment
sm.order=10
sm.defaultValue=true
• To build the runtime resource into the codebase for all the resource info files
for a particular directory, use the following command:
ResourceBuild <directory_relative_to_src>
For example:
ResourceBuild wt/example
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.
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 (see Managing Client JAR Files in the
Managing Customizations chapter on page 5-14) so clients can access the new
values.
3. Restart any Java clients. (HTML clients access the new values as soon as their
pages are refreshed from the server.)
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.
Topic Page
The Object Reference Design Pattern ...............................................................35-2
The Business Service Design Pattern................................................................35-3
The Master-iteration Design Pattern .................................................................35-7
35-1
The Object Reference Design Pattern
One of the most basic design patterns is the object reference design pattern.
Notice the property in bold type named "InitialValue" and its value, "new
ServiceFwd()." This property setting directs the code generator to make an
initializer for the "service" instance to what is specified as the value. The service
name appended with "Fwd" is the name of the class generated for a class
stereotype as being a "RemoteInterface."
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
stereotyped as a "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.
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.
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.
The Iterated interface provides an abstraction of a plug-and-play component in
conjunction with the Mastered interface. The intent is that, in a business model, an
object would assert that it is an iteration (instance) by inheriting the Iterated
interface. With this assertion, the business object can then be incrementally
Topic Page
Overview ...........................................................................................................36-2
Service Management .........................................................................................36-2
Service Event Management...............................................................................36-4
Implementing Business Data Types ..................................................................36-8
Lightweight Services.......................................................................................36-18
Customizing service.properties .......................................................................36-24
Windchill Multi-object Operations .................................................................36-26
36-1
Overview
Developing server logic is primarily a task of designing and implementing
business data types and services. To develop these kinds of abstractions, you must
understand applicable Windchill design patterns, service and event management
in general, and guidelines used in detailed design and implementation.
A business data type can be characterized as an important piece of information
known in the business domain. This information consists of data and/or state once
it exists and is recognized in the system. A business service can be characterized
as a set of one or more functions that carry out business-specific processing. The
purpose of these kinds of abstractions is to separate the entity objects from control
objects. Once they are separated, developmental impacts and risks, typically
caused by evolving requirements and behavior, are reduced. That is, data and
behavior changes are less likely to directly affect each other given sound
abstraction and encapsulation.
In addition to the information presented here, see the Windchill Design Patterns
chapter on page 35-1. That chapter describes design patterns that represent
Windchill’s current best practices regarding development of server logic.
See the Windchill Services chapter on page 31-1 for a description of standard,
reusable Windchill services.
Service Management
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.
getManagerService().addEventListener(
new ServiceEventListenerAdapter(
this.getConceptualClassname() ) {
public void notifyVetoableEvent( Object event )
throws WTException
PersistenceManagerEvent pmEvent =
(PersistenceManagerEvent)event;
Persistable target = pmEvent.getTarget();
if (object.getLock() != null) {
if (object.getLock().isSeized()) {
if (!object.getLock().getLocker().getObjectId().equals(
(Object) PersistenceHelper.getObjectIdentifier(
SessionHelper.manager.getPrincipal() )))
try {
trx.start();
insert(obj);
dispatchVetoableEvent( PersistenceManagerEvent.POST_STORE,
obj );
trx.commit();
trx = null;
}
finally {
if ( trx != null )
trx.rollback();
}
return obj;
}
Constraining an Attribute
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."
Validation Example
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.
Persistent Attribute
try {
SessionHelper.manager.setAdministrator(); //
}
catch (UserNotFoundException wex) {
System.err.println ("Administrator user
doesn’t exist (OK if installation)");
return;
}
finally {
SessionContext.setContext(previous);
// restore initial SessionContext
}
}
try {
trx.start();
dispatchVetoableEvent( PersistenceManagerEvent.PRE_STORE,
obj );
checkStore(obj);
obj.checkAttributes();
insert(obj);
dispatchVetoableEvent( PersistenceManagerEvent.POST_STORE,
obj );
trx.commit();
trx = null;
}
finally {
return obj;
//##end store% [ ]3458AD98008C.body
}
if (!object.getLock().isSeized()) {
if (AccessControlHelper.manager.hasAccess( locker.getPrincipal(),
object, WTPermission.MODIFY )) {
dispatchVetoableEvent( LockServiceEvent.PRE_LOCK, object );
object.getLock().seize( locker, note );
try {
trx.start();
PersistenceServerHelper.manager.update( (Persistable)
object, LEAVE_MODIFY_DATE );
trx.commit();
trx = null;
}
finally {
if (trx != null)
trx.rollback();
return object;
//##end lock% [ ]342A8DDB0271.body
}
logger.log("a message");
import wt.util.WTContext;
import wt.method.RemoteMethodServer;
import wt.method.RemoteAccess;
import wt.fc.QueryResult;
import wt.fc.PersistenceHelper;
import wt.fc.PersistenceManager;
import wt.part.WTPart;
import wt.part.WTPartMaster;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
WTContext.init(this);
action = new Button ("Get Parts");
this.add(action);
rel = new RunnerEventListener();
action.addActionListener(rel);
partNames = new Label( " with names like ... " );
this.add(partNames);
text = new TextField("", 25);
this.add(text);
queryCount = new Label( "Number of parts to return" );
this.add(queryCount);
countVal = new TextField( "5", 4);
this.add(countVal);
feedback = new TextArea("",10, 40);
this.add(feedback);
feedback.setText("");
try
{
Integer cnt = null;
try {
cnt = new Integer(count);
}
catch (Exception e) {
// some parse exception, just get default count
try {
cnt = new Integer(5); // this will work
} catch (Exception e2){}
}
try {
//
// Use feedback mechanism to send progress updates
// to the user
// and of course be sure to Localize it
//
QuerySpec queryspec = new QuerySpec(WTPartMaster.class);
queryspec.appendSearchCondition(
new SearchCondition(WTPartMaster.class,
WTPartMaster.NAME,
SearchCondition.LIKE,
name) );
QueryResult queryresult =
PersistenceHelper.manager.find(queryspec);
// create a vector of PartMasterInfo object to return
// to the client
while (queryresult.hasMoreElements()) {
wtpm = (WTPartMaster)queryresult.nextElement();
parts.addElement(new PartMasterInfo(wtpm.getName(),
wtpm.getNumber()));
if (++i >= count)
break;
}
1. 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.
4. Restart the method server in order for the change to take effect.
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.
Topic Page
Enterprise Abstractions .....................................................................................37-2
Document Abstractions ...................................................................................37-10
Part Abstractions .............................................................................................37-13
Change Abstractions........................................................................................37-21
37-1
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.
Business classes should be extended from one of the abstract classes included in
the wt.enterprise package to take advantage of the capabilities and services they
offer. This diagram shows convenience classes designed to consolidate a basic set
of features that various business classes might require. Most of the business
classes in your model are expected to extend one of these classes and simplify
your implementations.
Doc Package
Design Overview
The following figure illustrates the basic concepts encapsulated by the Windchill
part reference implementation.
The part classes are implemented based on the pattern established for revision
controlled objects in the wt.enterprise package. These classes, WTPartMaster and
WTPart, provide concrete classes exhibiting the management characteristics
established in wt.enterprise and add specifics for parts. The properties of a part are
specified on the WTpart class. Then, for normalization purposes, the sum of the
properties are stored on the WTPartMaster.
The part package is an example of implementing a Revision Controlled Business
subclass. The concrete part business classes inherit from the Revision Controlled
Business model (Master and RevisionControlled) template in the enterprise
model. Part inherits most of its functionality from the enterprise object
RevisionControlled. RevisionControlled pulls together the following plug and
play functionality: Foldered, Indexable, Notifiable, DomainAdministered,
AccessControlled, BusinessInformation, LifeCycleManaged, Version, Workable,
and Changeable.
WTPart Properties
WTParts can use other parts to build assemblies using the WTPartUsageLink as
shown in the following figure.
WTPartConfigSpec
Both of these links can be navigated using the Persistence Manager’s navigate
APIs. In addition, the WTPartService offers getAlternatesWTPartMasters and
getAlternateForWTPartMasters methods for navigation of WTPartAlternateLinks
and getSubstitutesWTPartMasters and getSubstituteForWTPartUsageLinks
methods for navigation of WTPartSubstituteLinks. Both WTPartAlternateLinks
and WTPartSubstituteLinks are access controlled, so permission to perform
operations such as creation and deletion of links is defined using the access
control service.
Placeholders
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.
<<Abstract>>
ChangeIssue
0..n
FormalizedBy
0..1
<<Abstract>> 1 0..n <<Abstract>> 1 0.. n <<Abstrac t>>
ChangeRequest2 ChangeOrder2 ChangeActivity2
Address edBy2 IncludedIn2
1 0..1
ResearchedBy
0..n
<<Abstract>> AcceptedStrategy
ChangeAnalysis
1
<<Abstract>> <<Abstract>>
ChangeInvestigation ChangeProposal 0..1
DetailedBy
For the Windchill out of 0..n For the Windchill out of
the box change process, the box change process
there can be only one <<Abstract>> the UI does not expose
ChangeInvestigation per AnalysisActivity this relationship
ChangeRequest.
<<Interface>>
Changeable2
W TProductInstance2 <<Abstract>>
(from part) RevisionCont rolled
(from enterprise)
WTProduct
(from part)
Changeable Objects
Subject
Product
Product
Master
<<Abstract>>
Object ToObjectLink
(from fc)
RelevantAnalysisData AffectedActivityData
<<Abstract>>
AnalysisActivity 0..n 0..n 0.. n 0..n
<<Interface>> <<Abstract>>
0..n 0..n Changeable2 0..n 0..n ChangeActivity2
WTProductMaster <<Abstract>>
(from part) ChangeRequest2
0.. n 0..n
RelevantRequestData2 ChangeRecord2
SubjectProduct
This relationship identifies Changeable2
This relationship identifies
revisions which were created to satisfy a
Changeable2 revsions
Change Activity. These revisions are
which were relevant for a
either entirely new, or new revisions of
given Change Request.
existing objects.
<<Abstract>>
Object ToObjec tLink
(f ro m f c)
Interface layer
The interface classes simply implement the Persistable interface to indicate
that the change management classes are objects stored by Windchill.
Abstract classes
The abstract classes implement various Windchill plug and play interfaces
and enterprise package classes to obtain standard Windchill functionality.
Each abstract class implements ContentHolder (see the content package in the
Windchill Services chapter on page 31-1), which provides the ability to attach
files. In addition, each abstract class extends either Managed or
CabinetManaged (see the enterprise package, earlier in this chapter for an
explanation of these classes). The abstract classes also contain modeled
associations among change objects, and between change objects and product
information objects.
Concrete classes
The concrete classes contain modeled business attributes.
Change issue
The following figure shows the model for change issues:
<<Abstract>>
ChangeIss ue
<<Abstract>>
Identificat ionObjec t
(from fc)
WTChangeIssue
<<Int erface>>
Identified number : String WTChangeIs sueIdentity
(from fc) name : String
number : String
description : String
name : String
requester : String
<<Interface>>
Typed WTChangeIssueIdentity()
WTChangeIssue()
(from type) assignToObject()
WTChangeIssue()
setToObject()
checkAttributes()
getIdentity()
0..1
IssuePriority
HIGH : IssuePriority = toIssuePriority ("HIGH")
ME DIUM : IssuePriority = t oIssuePriorit y(" MEDIUM" )
LOW : IssuePriority = t oIss uePriorit y(" LOW ")
EMERGENCY : IssuePriority = t oIssuePriorit y(" EMERGENCY" )
0..1
Category
SAFETY_ISSUE : Category = toCategory("SAFETY_ISSUE")
COST_REDUCTION : Category = toCategory("COST_REDUCTION")
DESIGN_ISSUE : Category = toCategory("DESIGN_ISSUE")
QUALITY_IMPROVEMENT : Category = toCategory("QUALITY_IMPROVEMENT")
OTHER : Category = toCategory("OTHER")
<<Interface>>
<<Interface>> <<Abstract>>
Typed
Identified ChangeRequest2
(from type)
(from fc)
Category
SAFETY_ISSUE : Category = toCategory("SAFETY_ISSUE")
COST_REDUCTION : Category = toCategory("COST_REDUCTION")
DESIGN_ISSUE : Category = toCategory("DESIGN_ISSUE")
QUALITY_IMPROVEMENT : Category = toCategory("QUALITY_IMPROVEMENT")
WTChangeRequest2 0..1
OTHER : Category = toCategory("OTHER")
number : String
name : String
description : S tring RequestPriority
needDate : Timestamp HIGH : RequestPriority = toRequestPriority("HIGH")
MEDIUM : RequestPriority = toRequestPriority("MEDIUM")
WTChangeRequest2() 0..1 LOW : RequestPriority = toRequestPriority("LOW")
WTChangeRequest2() EMERGENCY : RequestPriority = toRequestPriority("EMERGENCY")
checkA ttributes()
Complexity
SIMPLE : Complexity = toComplexity("SIMPLE")
0..1 COMPLEX : Complexity = toComplexity("COMPLEX")
<<Abstract>>
IdentificationObject
(from fc)
WTChangeRequest2Identity
number : String
name : String
WTChangeRequest2Identity()
assignToObject()
setToObject()
getIdent ity()
<<Abstract>> <<Abstract>>
ChangeInvestigation Ident ificat ionObject
(from fc)
<<Interface>>
Ident ified
(from fc)
WTChangeInvestigation
WTChangeInvestigationIdentity
number : String
number : String
name : String
name : String
description : String
<<Interface>> needDate : Timestamp
Typed WTChangeInvestigationIdentity()
results : String
(from type) assignToObject()
setToObject()
WTChangeInvestigation()
getIdentity()
WTChangeInvestigation()
checkAttributes()
<<Interface>> <<Abstract>>
ChangeProposalIfc ChangeAnalysis
WTChangeProposal WTChangeProposalIdentity
<<Interface>>
<<Abstract>> <<Abstract>>
Identified
(f rom f c)
Analys isAct ivit y IdentificationObject
(f rom f c)
WTAnalysisActivity
WTAnalysisActivityIdentity
number : String
<<Interface>> name : String name : String
Typed des cription : String number : St ring
(f rom t ype) needDate : Timest amp
results : String W TAnaly sisActivit yIdentity()
assignToObject()
W TAnalys isAct ivit y() s etToObject()
W TAnalys isAct ivit y() getIdentit y()
checkAtt ributes ()
WTChangeOrder2 WTChangeOrder2Identity
number : String number : String
name : String name : String
description : String
needDate : Timestamp getIdentity()
WTChangeOrder2Identity()
WTChangeOrder2() setToObject()
WTChangeOrder2() assignToObject()
checkAttributes()
Topic Page
Overview ...........................................................................................................38-2
Persistence Manager..........................................................................................38-2
Query .................................................................................................................38-4
Transaction ........................................................................................................38-8
Paging................................................................................................................38-9
Referential Integrity ..........................................................................................38-9
Multi-object CRUD Persistence Manager APIs..............................................38-12
Batch (update where/delete from) Statement Capabilities ..............................38-13
Transaction Context and Listeners ..................................................................38-14
Referential Integrity Association Validation During Object Delete ...............38-15
Persistence Datastore Sequence Customization ..............................................38-16
38-1
Overview
The PersistenceManager is an interface for database access. To use the
PersistenceManager, a class must implement the wt.fc.Persistable interface. By
implementing Persistable, the classes have the necessary code generated to read
and write data to and from the database and display its identity. Applications
should access the PersistenceManager through a convenience class named
PersistenceHelper. The PersistenceManager operations support events associated
with the operation. Application code can listen for these events and perform some
related action in the same transaction.
Operations that fetch objects from the database perform access control checks on
each object returned in the result set. These query operations use
wt.query.QuerySpec to define the classes of objects to select from the database.
QuerySpec uses the wt.query.SearchCondition class to define search criteria. That
is, in the SELECT statement that is generated, the QuerySpec defines which
columns to select and which tables to select from, and SearchCondition defines
the WHERE clause. The fetch operations return wt.fc.QueryResult.
The operations that delete, modify, and store a Persistable object all perform
access control checks before continuing with the operation. These operations
return the Persistable object with updated persistence information.
Support for large result sets and long running queries is provided via the paging
mechanism. Much like a web search, paging allows the user to execute a query
and view results in pages via fetch requests. Result pages are defined in terms of
an offset and range. A paging session corresponding to a specify query is
available for paging fetch requests for a limited amount of time. This is due to the
limited system resources that must be used to implement the paging session.
Therefore, the user must be prepared to handle exceptions caused by a paging
session timeout.
Persistence Manager
The PersistenceManager is the base business manager that other managers use to
handle persistence. For programming convenience, a helper class has been
implemented to facilitate client (and server) usage of the PersistenceManager
methods. The name of the class is PersistenceHelper. The wt.fc package Javadoc
Persistence Manager
QuerySpec
QuerySpec is used as an argument on the find and navigate operations to define
the classes of objects to retrieve. The SearchCondition object (described later in
this section) defines the criteria on those classes.
Since this is usually not the desired result, search conditions are used to limit the
number of objects returned. For example, to add a search condition to the
QuerySpec, use the following form:
QuerySpec.appendWhere(WhereExpression where,
int[] classIndices)
The classIndices parameter is used to apply the search condition to the appropriate
classes in the QuerySpec. The classes referenced from the SearchCondition must
match the QuerySpec classes at the specified index.
The targetClass is the class of the "other side role" in the navigate.
SearchConditions can be appended based on either the target or the link.
CompositeWhereExpression where =
new CompositeWhereExpression(LogicalOperator.AND);
where.append(new
SearchCondition(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NAME,SearchCondition.EQUAL,"XYZ"));
where.append(new
SearchCondition(wt.part.WTPartUsageLink.class,
WTAttributeNameIfc.CREATE_STAMP_NAME,true,
new AttributeRange(beginTime,endTime)));
qs.appendWhere(where, new int[] {0, 1});
SearchCondition
The number of objects retrieved by a QuerySpec is limited by criteria defined with
SearchCondition. The most common format of a SearchCondition constructor is
as follows:
SearchCondition(Class targetClass, String attributeName, String operation,
Object value)
The targetClass can be a concrete class, abstract class, or interface. When
appended to a QuerySpec, the SearchCondition is responsible for creating a
WHERE clause on the query.
The attributeName can be any attribute of the target class that maps to a column in
the table being queried. In the case of a target class that has AutoNavigate
associations to other classes, any attributes that map to columns in the base class
or associated class can be used. Not all attribute types can be used in a search
condition, for example, attributes stored in BLOB columns. To verify which
attributes can be used, inspect the InfoReport for the target class, looking at the
attribute’s PropertyDescriptor to ensure that its QUERY_NAME property is not
null.
QueryResult
The QueryResult object is the standard container returned from all Persistence
queries and navigations. QueryResult implements the standard
java.util.Enumeration plus the added abilities to determine the number of objects
in the QueryResult and reset the QueryResult to process it again.
Example: (using the QuerySpec created in the previous section):
QueryResult qr =
PersistenceHelper.manager.navigate(thePart,
wt.part.WTPartUsageLink.USES_ROLE,qs,false);
The difference between the two is that appendClassList() always adds a new class
to the QuerySpec. If the method addClassList() is used and the specified class is
already in the QuerySpec, the index of the existing class is returned. The index
returned when adding (or appending) a class is used when appending a search
condition for that class.
When using multiple class queries, all of the classes usually should be joined to
avoid redundant results. Use the following constructor for SearchCondition to join
two classes:
SearchCondition(Class targetClass, String targetAttribute,
Class linkClass, String linkAttribute)
// Join the WTPart class to the View class via the View object
ID and
// the WTPart Foreign Key
SearchCondition sc = new SearchCondition(wt.part.WTPart.class,
wt.part.WTPart.MASTER_REFERENCE + "." +
WTAttributeNameIfc.REF_OBJECT_ID,
wt.part.WTPartMaster.class, WTAttributeNameIfc.ID_NAME);
qs.appendWhere(sc, new int[] { partIndex, partMasterIndex });
If you create a transaction in which to perform some activities but never reach
your commit statement, be sure you mark the current transaction for rollback.
Someone else may accidentally ground out an exception and later try to commit
your partially completed work. The rollback call in a finally block, marks any
enclosing transaction so partial results cannot be accidentally committed later. If
code following notices a problem and calls rollback, the database is safe but, if
your code is the deepest transaction, it is your responsibility to call rollback if you
do not get to your commit call. Because you may not know for certain if your code
is the deepest transaction at the time an exception is thrown, you should always do
it.
try
{
PagingQueryResult pagingResults = null;
int offset = 0;
int range = 0;
int totalCount = 0;
boolean done = false;
while(true)
{
// Prompt user for offset and range
offset = ..;
range = ..;
done = ..;
if(done)
{
break;
}
if(pagingResults == null)
{
// Open Paging Session
pagingResults = PagingSessionHelper.openPagingSession(
offset, range, a_querySpec);
pagingSessionId = pagingResults.getSessionId();
totalCount = pagingResults.getTotalSize();
else
{
pagingResults = PagingSessionHelper.fetchPagingSession(
if(pagingSessionId <= 0)
{
// No paging session was established
break;
}
}
}
finally
{
if(pagingSessionId > 0)
{
PagingSessionHelper.closePagingSession(pagingSessionId);
}
}
}
When to use
The batch update/delete operations represent the most performant option for
affecting change in the database because they minimize both the data needed to
perform the operation and the data needed to affect the change – neither requires
that the objects to be changed first be retrieved from the database and only the
columns to change need to be sent (as opposed to full persistables) in the case of
an update.These APIs should be considered when:
• There is no need to bring the object back into the VM, either to perform tests
or to dispatch events
• None of the objects involved in the batch operation exist in memory prior to
the batch operation
In most cases, it is sufficient to say that their use should be limited only to cases
where there is never a need to bring the object – or its reference – back to memory
and should never be used on objects already in memory. The above guidelines are
based on the fact that the performance benefits drop when the data is actually
needed and by the fact that the changes won't be reflected in any of the in-memory
objects.
However, a gray area for batch update is in cases where the references are needed
for event dispatch, the dispatched event indicates that the change has occurred,
and the listeners need not inflate.
MyCache myCache;
// member class for service events
class MyListener extends ServiceEventListenerAdapter {
public void notifyVetoableEvent (Event e) {
KeyedEvent keyedEvent = (KeyedEvent) e;
Object targetObject = keyedEvent.getEventTarget ();
//
// check out event and object to see if we really care
what happens
//
// Set up with Transaction for commit
if (keyedEvent.getEventType ().equals
(PersistenceManagerEvent.POST_DELETE)) {
Transaction.addTransactionListener(new
Remover(targetObject));
}
}
}
// member class for transaction events
class Remover implements TransactionListener {
Object obj;
public Remover (Object obj) {
this.obj = obj;
}
public notifyCommit() {
// get my cache and remove object
getMyCache().remove(this.obj);
}
public notifyRollback() {
// ignore
}
}
public void performStartupProcess () {
myListener = new MyListener() // subclass of
ServiceEventListenerAdapter
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
Information Modeler (i.e. Rose) 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 using Information Modeler.
Solution Elements
2. Specify the sequence properties. Open the Class Specification dialog for the
class, select the "Windchill" tab, and choose the "Sequence" value from the
"Set" drop down list. Specify the initial seed and increment values if the
defaults are not sufficient.
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)
SQLServer
The following is a sample script for a partNumber sequence that begins with 1 and
has an interval of 20.
CREATE TABLE wt_sequence_partNumber (dummy CHAR(1), value BIGINT
IDENTITY(1,20))
go
CREATE PROCEDURE wt_get_next_sequence_partNumber
AS
INSERT wt_sequence_partNumber (dummy) VALUES ('x')
Note: See your installed Windchill Javadoc entries for the wt.query package for
further information, including database-specific support for SQL functions and
keywords.
Topic Page
QuerySpec .........................................................................................................39-2
SearchCondition ................................................................................................39-9
39-1
QuerySpec
The QuerySpec contains the following attributes and APIs for building complex
query expressions.
Note that when the WTPart class is appended to the query, the selectable
parameter is false. The full object is not returned; only the number column is
returned.
Results are still returned in the QueryResult object. Each element of the
QueryResult corresponds to a row and is an Object array (that is, Object[]). In this
example, the number column is at index 0 for each element. The actual Java type
for each result is based on the table column and the JDBC SQL-to-Java type
mapping.
The behavior of queries for parent classes (that is, classes that have one or more
persistable, concrete subclasses) is to execute SQL for each table. When only
ColumnExpressions are included in the SELECT clause, all of these SQL
statements are implicitly executed as a single UNION statement instead of
multiple separate database queries.
Queries that include only column expressions still have Access Control applied.
Internally, columns are added to the query to retrieve information needed for
Access Control. When queries containing only columns are used as sub-selects as
part of an ObjectReference query (described later in this section), then the Access
Control columns are not added. This behavior is important to understand when
using aggregate SQL functions. When these are used, the SELECT clause must
contain only expressions with aggregate SQL functions (or the expression must be
included in the GROUP BY clause. If Access Control is applied to such a
statement, then it will result in invalid SQL.
The following example builds a query against a non-modeled table named dual:
QuerySpec qs = new QuerySpec();
int fromIndex = qs.appendFrom(new
ExternalTableExpression("dual"));
TableColumn dummyColumn = new TableColumn("dual", "dummy");
SQLFunction currentDate = SQLFunction.new
SQLFunction(SQLFunction.SYSDATE);
qs.appendSelect(dummyColumn, new int[] { fromIndex }, false);
qs.appendSelect(currentDate, null, false);
In this next section, the criteria are constructed and appended to the query. Note
that the first SearchCondition uses two ClassAttribute instances. The
corresponding indices must be added to the fromIndices array that is used in the
appendWhere. Likewise, the second SearchCondition references the part class and
the third SearchCondition references the alternate part class. Therefore, four
fromIndices are required and each array element must correspond to the
appropriate SearchCondition.
CompositeWhereExpression orExpression =
new CompositeWhereExpression(LogicalOperator.OR);
orExpression.append(new SearchCondition(
SQLFunction.newSQLFunction(SQLFunction.SUB_STRING,
partNumber, subStringStart, subStringEnd),
SearchCondition.EQUAL,
SQLFunction.newSQLFunction(SQLFunction.SUB_STRING,
alternatePartNumber, subStringStart, subStringEnd)));
orExpression.append(new SearchCondition(
partName, SearchCondition.LIKE, wildcardExpression));
orExpression.append(new SearchCondition(
alternatePartName, SearchCondition.LIKE, wildcardExpression));
The last API explicitly specifies table expressions and aliases for the WHERE
expression operands. This API is used for correlated subselects. When using
subselects, it is common to use correlated columns (that is, a join between a
column in the outer select and a column in the subselect). This is supported using
the appendWhere() API in which TableExpressions and aliases are passed
explicitly. For WhereExpressions that do not involve a subselect, the
TableExpressions and aliases are derived implicitly using the QuerySpec FROM
clause and the specified indices.
The following example builds a query using an EXISTS clause and a correlated
subselect. The query will return all PartMasters for which an alternate PartMaster
The following code constructs the query specification. The outer select will return
PartMaster objects.
QuerySpec select = new QuerySpec();
int partIndex = select.appendClassList(wt.part.WTPartMaster.class,
true);
The following code constructs the subselect. The alias prefix is changed to avoid
conflicts with the outer select.
QuerySpec subSelect = new QuerySpec();
subSelect.getFromClause().setAliasPrefix("B");
int altIndex =
subSelect.appendClassList(wt.part.WTPartAlternateLink.class,
false);
subSelect.appendSelect(new ClassAttribute(
wt.part.WTPartAlternateLink.class, WTAttributeNameIfc.ID_NAME),
The following code explicitly sets up the TableExpressions and aliases, which are
passed as arrays. The join will be from the outer select to the subselect so the outer
select values are placed in the arrays at index 0 and the subselect values are placed
in the array at index 1. The arrays are then used to append the SearchCondition.
TableExpression[] tables = new TableExpression[2];
String[] aliases = new String[2];
tables[0] = select.getFromClause().getTableExpressionAt(partIndex);
aliases[0] = select.getFromClause().getAliasAt(partIndex);
tables[1] = subSelect.getFromClause().getTableExpressionAt(altIndex);
aliases[1] = subSelect.getFromClause().getAliasAt(altIndex);
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.
Note: The current version of the Oracle JDBC driver contains a bug that prohibits
using parentheses around component statements in a nested compound query. The
setting of the wt.pom.allowCompoundParentheses property in the db.properties
file controls whether parentheses are used. By default, this setting is false to avoid
the Oracle JDBC driver bug. This workaround could lead to unexpected results if
the set operator precedence is significant.
The following code constructs the query specification. The first select constructed
is for PartMasters with the name ENGINE.
QuerySpec partSelect = new QuerySpec();
int partIndex = partSelect.appendClassList(wt.part.WTPartMaster.class, false);
partSelect.appendWhere(new SearchCondition(wt.part.WTPartMaster.class,
WTPartMaster.NAME, SearchCondition.EQUAL, "ENGINE"), new int[]
{ partIndex });
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 });
altSelect.appendJoin(altIndex,
wt.part.WTPartAlternateLink.ALTERNATES_ROLE,
partIndex);
altSelect.appendJoin(altIndex,
wt.part.WTPartAlternateLink.ALTERNATE_FOR_ROLE,
altPartIndex);
Finally, the compound statement is constructed using the two previous queries
and the UNION set operator.
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 following code constructs the query specification. The first component query
is for Parts. Note the setting of the column alias.
String sortName = "sortName";
This next section constructs the Document portion of the query. The same column
alias is used.
Finally, the compound query is constructed using these two component queries.
The OrderBy is appended to the overall query. The default locale is used to sort
the names with respect to the user’s language.
CompoundQuerySpec query = new CompoundQuerySpec();
query.setSetOperator(SetOperator.UNION);
query.addComponent(partQuery);
query.addComponent(docQuery);
query.appendOrderBy(new OrderBy(partName, true
));
Join Support
Query joins are used for associating data contained in separate tables. Joins can be
accomplished by using the PersistenceManager navigate methods or through
adhoc WhereExpressions. The QuerySpec class also provides explicit support for
appending a join to a query using link classes and roles defined in the Rose model.
This offers the flexibility of the QuerySpec along with the simplicity of specifying
query joins using model information. The following QuerySpec methods can be
used.
appendJoin(int a_linkIndex, String a_role, Persistable a_source)
appendJoin(int a_linkIndex, String a_role, int a_targetIndex)
The following example builds a query that joins together the SubFolder and Part
classes via the FolderMembership link. The query returns all folders and all of the
associated parts that are contained in the folder. The following code constructs the
query specification. The first section adds the classes and the attributes that should
be returned. The final two lines of code join together the classes using the
modeled roles for the FolderMembership link class.
QuerySpec query = new QuerySpec();
Topic Page
Background .......................................................................................................40-2
The Windchill Approach ...................................................................................40-3
Localizing Text Visible to the User ..................................................................40-5
Resource Info (.rbInfo) Files .............................................................................40-8
40-1
Background
Changing an application for use in another country or culture is often thought of
as merely translating the language that appears in the user interface. There are
many other aspects, however, that you should consider when developing a global
application.
• How will you identify the preferred language and geographic location of the
user-
You may want to design into the application (or underlying product
architecture) the ability to determine the locale and present the appropriate
version from a collection of different localized versions.
• What data used within your application is sensitive to locale-
Consider the use of decimals within numbers, currency symbols, date formats,
address styles, and system of measurement.
• How should data be formatted-
Consider the order in which text and numbers are read by different audiences.
Languages that display numbers from left to right and text from right to left
affect the layout of menu bars and text entry fields. The grammar of a
language may dictate different placement of variables in error messages.
• Collation of sortable lists
Consider how different alphabets affect the collation sequence and how
collation of typical list elements is done in the locales of potential users of
your application.
• Non-Roman alphabets
Your application must be able to accommodate different fonts and different
sizes of fonts. This again can affect the layout of menu bars and text entry
fields.
• What are the cultural sensitivities toward graphics and use of color-
When designing icons or other graphics, and deciding on background and
other colors, consider whether they may be objectionable in another culture
Both client and server developers need to be aware of these factors. You must be
able to localize not only the GUI, but also feedback messages and exceptions that
might be displayed to the user.
associates the label defined internally as lblUser with the string found in the
resource bundle that corresponds to the lblUser key; that is,
{"lblUser","User"},
//{{DECLARE_MENUS
//}}
}
private void localize() {
RB=ResourceBundle.getBundle("wt.clients.administrator.LabelsRB"
,getLocale());
lblUser.setText(RB.getString("lblUser") + ":");
btnSearch.setLabel(RB.getString("btnSearch"));
btnCreate.setLabel(RB.getString("btnCreate"));
btnUpdate.setLabel(RB.getString("btnUpdate"));
btnAddUsertoGroup.setLabel(RB.getString
"btnAddUsertoGroup"));
btnView.setLabel(RB.getString("btnView"));
btnDelete.setLabel(RB.getString("btnDelete"));
btnClose.setLabel(RB.getString("btnClose"));
try {
//MultiList column headings
java.lang.String[] tempString = new java.lang.
String[4];
tempString[0] = RB.getString("Full Name");
tempString[1] = RB.getString("UserID");
tempString[2] = RB.getString("Web Server ID");
tempString[3] = RB.getString("E-Mail");
lstUsers.setHeadings(tempString);
}
catch (PropertyVetoException e) {}
}
To create a different localization for this resource bundle, for example, French,
you would create a new class in the wt.clients.administrator package called
LabelsRB_fr. This class would contain the same label keys, such as
"lblAdministrative" but its value would be "administratif" rather than
"Administrative". All the other values would likewise be changed to their French
counterparts. You would compile the new class; then the Java runtime would be
able to find a French resource bundle for the Administrator client.
wt.L10N.complete
Resource Info files are an alternative to storing localizable text in
ListResourceBundle source code files. They are structured properties files that
facilitate easy manipulation by automated tools.
Resource info (or rbInfo for short) files are resource files used to store localizable
strings of Java programs. The primary purpose of the rbInfo files is to provide an
easier and more manageable way to handle localizable strings than resource
bundles. RbInfo files offer a number of advantages over resource bundles:
• Resource bundle files are Java source files, so that a single misplaced curly
bracket, missing double quote or extra comma will cause a syntax error and
break the compile and integration process. RbInfo files have much simpler
format, it is easier to localize and more difficult to introduce syntax errors.
• Because of the simpler format of the rbInfo files, it is easier to handle them
with localization tools; perform change tracking, change propagation and so
on.
• It is more difficult to abuse the rbInfo file format and introduce ’tricky’
resource types. Java resource bundles can hold any type of objects, but rbInfo
files can handle strings only. (This may appear to be a limitation, but it is not.
It makes localization easier.)
RbInfo files are converted to compiled Java class files in the integration process,
so that the same naming convention rules apply to rbInfos as resource bundles.
(Localized versions are kept in separate files; there is one resource file per
language, the name of the locale is appended to the name of the localized files.)
The format of the rbInfo files is PTC-specific. It was designed primarily for
Windchill, but can be used in other Java-based products as well. The migration
from resource bundles to rbInfo files is seamless; there is no need to change the
source code. Old resource bundles can be converted to rbInfo format using a
relatively straightforward process. To find out more about the migration, refer to
the Windchill Upgrade and Migration Guide.
<key>.order Explicit sort order for the value, Message text: Unused
unused for alpha ordering.
Metadata: Unused
EnumeratedType: Optional
Message Text
The Message Text category most commonly contains error messages and labels
for user interface actions, but is the general category for any localizable text that
does not fall into one of the other categories. The Message Text files are
completely user-maintained, while the maintenance of the entries in the other two
categories is automated via various generation tools. Since this category is not
maintained by automated tools, and since the resulting run-time bundle is the
same ListResourceBundle subclass that it would be if the information were stored
in a ListResourceBundle source code file, the use of .rbInfo file format is optional
for Message Text.
The following sections describe the resource info files for Message Text.
The first line classifies the resource info and should never be changed. The values
of the second and third lines can be changed by the owner of the package, if the
file can be customized, and/or the file is deprecated.
lblAdministrative.value=Administrative
lblAdministrative.constant=LBL_ADMIN
lblAdministrative.comment=administrative ui label
lblAllGroups.value=All Groups
lblAllGroups.constant=LBL_ALL_GROUPS
//Button Labels
btnAdd.value=Add>>
btnAdd.constant=BTN_ADD
btnAddAll.value=Add All>>
btnAddAll.constant=BTN_ADD_ALL
Archive and Purge allow you to remove data from your Windchill system while
preserving a reasonable working set of data for end users. You have the ability to
couple archive functionality with purge so that while data is removed from the
production system, an archive of that data still exists to be retrieved as required.
Note: In order to access the archive functionality, you must install Windchill
Archive.
Topic Page
Archiving Related Classes.................................................................................41-2
Enabling Archive/Purge/Restore for Custom Classes.......................................41-4
Customizing Archive Upgrade..........................................................................41-8
41-1
Archiving Related Classes
Note: All objects that need to be archived must implement the
wt.fc.archive.Archiveable interface.
When creating an archive, Windchill gives you the ability to specify which
versions and iterations and which dependencies should be included with the item
selected for archival. The choices for each of these two options are as follows:
• CAD Dependencies: Required dependencies or All dependencies. This
choice pertains to CAD dependencies the same way it does elsewhere in the
product.
• Version and Iterations: Latest iteration of latest version or Latest iteration
of each version: This logic (in some cases) recursively collects objects based
on a list of link objects that connect archive-supported objects in Windchill.
This enables Windchill to recreate the object with enough contextual information
to use it meaningfully after restore, even if all such information has been deleted
from active use from the Windchill instance at the point of restore.
Out of the box, Windchill takes a "safety first" approach and collects all the
supported contextual objects (barring exceptions) for the Versions and Iterations
category of related items.
The list of supported objects is as follows:
wt.epm.structure.EPMMemberLink
wt.epm.structure.EPMVariantLink
wt.epm.structure.EPMReferenceLink
wt.epm.build.EPMBuildHistory
wt.epm.structure.EPMContainedIn
wt.part.WTPartUsageLink
wt.part.WTPartReferenceLink
wt.part.WTPartDescribeLink
wt.epm.build.EPMBuildLinksRule
For your business objectives, a subset of the above list may make more sense
and/or you may need to add customized links to the list. The following
information describes the way related objects are collected by Windchill; this
needs to be understood to customize this behavior:
• Windchill uses wt.dataops.objectcol.RelationshipMapDef objects and
wt.dataops.objectcol.RelationshipMap objects to control the collection of
related objects.
• Windchill loads one wt.dataops.objectcol.RelationshipMapDef object, that
holds the traversal map for related objects based on
<Windchill>/loadFiles/content/RelationshipMap.xml file, as part of the base
data loading.
• Windchill loads four wt.dataops.objectcol.RelationshipMap objects that use
the above loaded wt.dataops.objectcol.RelationshipMapDef object and
Introduction
This section describes the procedure for enabling the archive, purge, and restore
of custom classes. Specifically it discusses the creation of Import Export (IX)
handlers for those classes and steps for configuring the IX and
Archive/Purge/Restore Framework.
The following steps need to be performed in order to achieve this.
• Write IX handlers for all custom classes, including relationship classes.
• Make appropriate entries for the new classes in coreobjects.dtd ,
coreX05.xml.
• Make appropriate entries in RelationshipMap.xml
Writing Handlers
You will need to create IX handlers for all your custom classes including your link
classes.
Refer to the How to Write Exp/Imp Handlers section in the Import Export
Framework chapter on page 42-17. In addition you can refer to the
implementation of handlers for WTPart and WTDocument. Alternatively you can
derive your handlers from existing handlers and reuse the code.
Apart from importing normal attributes, you need to export and import certain
additional attributes.
To do this use the wt.ixb.archive.ArchiveHndHelper class. This class provides
helper methods that IX handlers need to support Archive and Restore
functionality. In your IX handler you should check to see whether archive/restore
is being done. In this case you must also perform certain operations on the
archive-specific attribute. To export/import Archive-related attributes use the
ExpImpForFlexibleVersioningAttr, ExpImpForArchiveAttr,
ExpImpForMarkUpAttr classes.
You can refer to the IX Handler for WTPart for details.
The following examples show sample code that is added to various methods to
enable archive/restore.
• protected void exportAttributes (Object object, IxbDocument fileXML,
Exporter exporter)
if (ArchiveHelper.isArchiveRestoreContext(exporter)) {
IxbHndHelper.exportAttribute(ExpImpForFlexibleVersioningAttr.class, ob, fileXML,
exporter);
The above code will ensure that Archive and Flexible Versioning attribute
information is also stored in the archive.
• public void checkConflicts (IxbElement fileXML, Importer importer)
If you are implementing this method you should also include the code below.
if (ArchiveHelper.isArchiveRestoreContext(importer)) {
IxbHndHelper.checkConflictForAttribute(ExpImpForFlexibleVersioningAttr.class,
existingOb, fileXML, importer);
IxbHndHelper.checkConflictForAttribute(ExpImpForArchiveAttr.class, existingOb,
fileXML, importer);
}
• If your handler classes do not extend from existing handler and your classes
are not derived from an out-of-the-box class you will also need to override the
storeObject method to ensure that your objects are created with the same
OIDs they had before archive/purge.
public Object storeObject( Object object, IxbElement fileXML, Importer importer )
For example,
ObjectIdentifier oid = ((Persistable)
object).getPersistInfo().getObjectIdentifier();
ArchiveHndHelper.addOidForReuse(Transaction.getCurrentTransaction(), oid);
PersistenceHelper.manager.save(object) ;
Recreate the schema for the Dataops module and load the XML file into the
database using the LoadFromFile mechanism. For example,
windchill wt.load.LoadFromFile
Limitations
• For archive information to be stored objects need to implement at least the
Iterated and Ownable interfaces.
• For storing Archive attribute information your classes need to be Iterated and
Ownable.
• For storing Flexible attribute information your classes need to be Iterated and
Federatable.
• If your classes are not Iterated and Ownable you will not be able to store
Archive information, however you can import/export your custom attributes,
and restore the OIDs as this only requires your classes to be Persistable.
CAPTION
Testing Restore
The generated artifacts should be tested on a test system by restoring old archives
containing customized objects prior to deploying on a production system.
This chapter describes the Import Export (IX) Framework and explains how to
customize and use it for various solutions.
Topic Page
Overview ...........................................................................................................42-2
How to Write an IX Application .......................................................................42-3
How to Write Exp/Imp Handlers.....................................................................42-17
Navigating Through an Object’s Structure with ObjectSet Application.........42-26
Product Design eXchange (PDX) Support for Export ....................................42-46
42-1
Overview
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.
Where CLIENT_JAR is the complete client side file path, e.g. c:\\
mydocuments\\impex.jar
Exporter Class
The details of the exporter class are as follows:
Definition:
public class Exporter extends ExpImporter{…};
Constructor:
Exporter (ApplicationExportHandler _applicationExportHandler,
String targetDTD,
IxbElement localMappingRules,
File policyRuleFile) throws WTException {
super ("export", localMappingRules);
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 used in
Windchill 9.0 is standardX10.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.
The following XML rule file overrides the Team Template attribute, and no matter
what team an object belonged to when it was exported, its team template attribute
will be “Change Team” in the “/System” domain.
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>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
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.
<!--
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:when>
<xsl:otherwise>
<action>Lock</action>
</xsl:otherwise>
</xsl:choose>
</actionInfo>
</xsl:template>
-->
</xsl:stylesheet>
Note: A list of available export handlers is created based on XML files in the
folder <WC_home>\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 the part “How to
write Export Handler” 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 one by
one. Let’s assume that those objects are in a set called res, then you can export
them like this:
Iterator iter = res.iterator();
while (iter.hasNext()) {
Persistable obj = (Persistable)iter.next();
exporter.doExport(obj);
}
Note: This option cannot work without a policy file to specify the new object
identities.
The format of new information that must be provided in ImportPolicy file is:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<!--
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>
-->
<xsl:template match='WTPart'>
<actionInfo>
<action>PickExistingObject</action>
</actionInfo>
</xsl:template>
<xsl:template match='WTDocument'>
<actionInfo>
<action>PickExistingObject</action>
</actionInfo>
</xsl:template>
<xsl:template match='EPMDocument'>
</xsl:stylesheet>
Note:
Importer class
Definition: public class Importer extends ExpImporter
Constructor:
Importer (ApplicationImportHandler _applicationImportHandler,
String _dtd,
String _ruleFileName,
Boolean _overrideConflicts,
Boolean _validate
) throws WTException
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 2 methods:
• targetDTD: string that specifies what DTD must be used for import
process. The IX framework will find appropriate handlers for objects and
Document Type Definition for objects based on this DTD string if the
imported file does not specify any. The DTD string used in Windchill 9.0 is
standardX10.dtd.
</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.
importer.finalizeImport();
All handlers for non-versioned objects (for example links, ReportTemplate ... )
extend the class ClassExporterImporterTemplate, and all handlers for
versioned objects (for example Parts, Documents, EPMDocuments ...) extend the
class ExpImpForVersionedObject.
Note: Handlers for non-versioned objects act like the previous versions.
If the real handler doesn’t implement the method importElement(…), then the
call invokes the default method importElement(…) of the class
ClassExporterImporterTemplate. In this class, the importElement(…)
method calls to
findAmongExistingObjects (fileXML, importer);
If it finds that the object in the XML file currently exists in the database, it will not
import the object. Otherwise, it will call the following methods:
Some of these methods should be implemented in the handler, and it is how and
when the real handler comes to do its job.
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>standardX10.dtd</dtd>
<targetTag>default</targetTag>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</classExporter>
DTD Files
In the folder Windchill\src\wt\ixb\registry\ixb\dtds\standardX10.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,
3. Override getRootTag() method, which returns the desired root tag for the
object type to be exported. The following is an example of this method for the
object of "MyClass":
protected String getRootTag() {
return "MyClass";
}
After adding this, the export handler for class may call this method to have the
part attribute exported.
<elementImporter>
<tag>
[class name of the object that will be imported without full
path name ]
</tag>
<dtd>
[String DTD, specifies where DTD for the class is stored]
</dtd>
<handler>
[class name of the handler that is used to import the object]
</handler>
</elementImporter>
For example:
<elementImporter>
<tag>WTPart</tag>
<dtd>standardX10.dtd</dtd>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</elementImporter>
All handlers with the <dtd> tag “standardX10.dtd” are handlers for import
object in R9.0.
Import handlers for non-versioned objects are quite straightforward, and any of
the following classes can be referred as example:
ExpImpForWTPartDescribeLink
ExpImpForWTPartReferenceLink
ExpImpForWTPartUsageLink
<elementImporter>
<tag>MyObject</tag>
<dtd>standardX10.dtd</dtd>
<handler>com.ptc.mypackage.ExpImpForMyObject</handler>
</ elementImporter >
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.
<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.
The navigation rule files reside in the folder Windchill\codebase\
registry\ixb\object_set_handlers.
Navigating Rules
There are two types of navigating rules: Generator and Filter.
Tags
<id>: Generator Id
<handler>: Navigator – Java class that helps navigating through the object
structure. In the example, to navigate through WTPart structure.
<dialogClassName> : Java class of the dialog that must be called from the GUI
to search the top-level object of this class in database (in this example, to search
WTPart).
<localizedName> and its sub tags are for internationalization purpose. The
string resource for displaying the Generator to the GUI will be defined in the
.rbInfo file specified by localizedName/localizedString/class and its
key in the .rbInfo file is localizedName/localizedString/key.
If you don’t want this GeneratorId to be displayed to the GUI, but only to be used
programmatically in your application, add the tag <display> like this:
<setGenerator>
<id>productStructureNavigator</id>
<display>false</display>
<handler>
wt.ixb.objectset.handlers.navigator.ProductStructureNavigator
</handler>
<dialogClassName>
wt.clients.ixb.exp.NavigatorSearchDialog
</dialogClassName>
<localizedName>
<localizedString>
<class>wt.ixb.objectset.objectSetResource</class>
<key>PRODUCT_STRUCTURE_NAME</key>
</localizedString>
</localizedName>
Note: If the tag <display> is not specified, or set to true, the Generator will be
included in the result of the method
ObjectSetHelper.getListOfObjectSetGenerators() and it will
be displayed in the GUI. If the tag <display> is false, the Generator will not be
included in the result of the method
ObjectSetHelper.getListOfObjectSetGenerators(), and it will
not be displayed to the GUI. To get all Generators in the system, use the method
ObjectSetHelper.getAllAvaiableGenerators().
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.
(From “<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>
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:
(File: “<Windchill>\codebase\registry\ixb\object_set_handlers\
filter_by_time.xml”)
<setFilter>
<id>filterByTime</id>
<handler>wt.ixb.objectset.handlers.FilterByTime</handler>
<dialogClassName>
wt.clients.ixb.exp.FilterByTimeDialog
</dialogClassName>
<localizedName>
<localizedString>
<class>wt.ixb.objectset.objectSetResource</class>
<key>FILTER_BY_TIME_NAME</key>
</localizedString>
</localizedName>
<parameters>
</parameters>
</setFilter>
The filtering mechanism, as well as the object collection are coupled with the
export application at the level of StandardIXBService. They can be separated.
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.computeObjectSetForGivenGeneratorsAndFilters(generatorIds,
generatorParams, filterIds, filterParams);
genId[0] = “productStructureNavigator”;
genParams[ 0] = “wt.part.WTPart:6789”;
WTHashSet objects = (WTHashSet) ObjectSetHelper.
computeObjectSetForGivenGeneratorsAndFilters(genIds,
genParams,
new String [0 ],
new String [0 ]);
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)
folderContent Collects all objects in Cabinet and Folder <class name: oid>, like:
a given
wt.folder.Subfolder:1234
Cabinet/Folder
or
(including
subfolders) wt.folder.Cabinet: 1234
productStructureNavi Collects all children Product Structure <class name: oid>, like:
gator of a given Part (built with active
wt.part.WTPart:1234 for
Config Spec)
(e.g. Parts, which it the top-level object. This
uses and Documents object must be instance of
which describe it) WTPart
productStructureNavi Collects all children CAD Document <class name: oid>, like:
gatorEPM of a given CAD Structure (built with
wt.epm.EPMDocument:12
Document active config spec)
34 for the top-level object.
This object must be
instance of EPMDocument
productStructureNavi Collects all children Product Structure <class name:oid>, like:
gatorWithEPM of a given Part with CAD
wt.part.WTPart:1234 for
including related documents (built
the top-level object. This
CAD Documents with active Config
object must be instance of
Spec)
WTPart
Filters list
Localized name – En (for
String id Description GUI) Parameters as String
Export Application
The current Windchill Export out-of-the-box GUI and the
StandardIXBService is an Export Application.
The out-of-the-box Windchill Export GUI is Export Application (client) that calls
export process in StandardIXBService (Export Application (server)) via
IXBHelper.
Without GUI:
IXBExpImpStatus status = IXBHelper.service.doExport(
boolean previewOnly,
String[ ] generatorIds,
String[ ] generatorParams,
String[ ] filterIds,
String[ ] filterParams,
IXBStreamer ruleFile,
boolean detailedLog,
String stDtd);
stDtd specifies which version of the Exp/Imp handlers will be used. This is
used to support backward compatible. If stDtd is null or empty (“”), the
STRING_DTD will be calculated based on the current Windchill.
When the method IXBHelper.service.doExport(…) is called, it will call to
the method doExportImpl(…) in the StandardIXBService.
This method:
• Creates a general export handler ExportHandler handler. This is an inner
class of StandardIXBService.
• Gets a list of objects that will be exported by calling:
ObjectSetHelper.computeObjectSetForGivenGeneratorsAndFilters
(
generatorIds,
generatorParams,
filterIds,
filterParams);
Import Application
The current Windchill Import GUI and StandardIXBService are the Import
Application. The current Windchill Import out-of-the-box GUI is Import
Application client that calls import process in StandardIXBService (Import
Application server) via IXBHelper.
Without GUI:
IXBExpImpStatus status = IXBHelper.service.doImport(
IXBStreamer ruleFile,
IXBStreamer dataFile,
boolean overrideConflicts,
boolean isPreview,
boolean detailedLog,
String creatorName,
String stDtd);
stDtd specifies which version of Exp/Imp handlers will be used. This is used to
support backward compatible. If stDtd is null or empty (“”), the STRING_DTD
will be calculated based on version of current Windchill system.
When the method IXBHelper.service.doImport(…) is called, it will call to
the method doImportImpl(…) in StandardIXBService.
This method:
• Puts creator name in WTContext to be used by import handler.
• Creates a general import handler ImportHandler handler.
• Gets a list of XML files from the Jar file to be imported by calling
jar.getFileNamesByExtension ("xml");
• Creates an instance of Importer, the class that does the import job.
• Depending on isPreview (true/false), the method doImportImpl(…)
calls the appropriate methods of Importer to do a preview or the real import:
– importer.doImport(stream);
– importer.doPreview(stream);
• The others (importer.doImport(fn, tag) and
importer.doPreview(fn,tag)) are for optimization, and they depend on
how XML files are named. This feature is just for a particular Exp/Imp
Application (wt.clients.ixb and StandardIXBService).
• Sends log messages back to client.
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){
throw new WTException(ioe);
}
}
//create exporter
Exporter exporter = null;
if ( policyFile==null ) { // policy rule is null; export action is expected
...
exporter = IxbHelper.newExporter(this, container, IxbHelper.STANDARD_DTD,
clientSettingsElement, null, actionName);
}
else{
exporter = IxbHelper.newExporter (this, container,
IxbHelper.STANDARD_DTD, clientSettingsElement, policyFile, null );
}
}
exporter.finalizeExport();
if ( !(actionName != null &&
actionName.equals(wt.ixb.tuner.ExportActionHelper.NO_ACTION_CMD) )){
trx.commit();
}
trx = null;
}
finally {
if (trx != null) {
return resJar;
}
}
import java.io.File;
import java.io.PrintStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;
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;
}
public InputStream getContentAsInputStream (String contentId)
throws WTException {
try{
return jr.getStreamByName (contentId);
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);
Supported APIs
• ExportPackage exportPackage =
ExportPackageForPDX.createExportPackageForPDX(…)
• PDXExportHelper.doExportToPDX(…)
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 generator types, e.g.
{"singleDocument", "productStructureNavigatorWithEPM"}
• generParams - Array of local id for the corresponding seed objects
Throws:
• wt.util.WTException
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 generator types, e.g.
{"singleDocument", "productStructureNavigatorWithEPM"}
doExportToPDX
Sample Program
PDXExportHelper.doExportToPDX(sourceContainer,(ExportPackageForPDX)exportPackage,
PDXExportHandler.XML_ATTR_ATTACHMENTS_OPTION, dir, "zipName");
Topic Page
Background Information ...................................................................................43-3
General Externalization Guidelines...................................................................43-4
Hand-coded Externalization Guidelines............................................................43-4
Migration Guidelines for Classes with Hand-coded Externalization................43-5
Examples of Generated Externalization Code for Evolvable Classes...............43-6
43-1
Externalizable classes that implement the Evolvable interface are the Windchill
classes that can be serialized into BLOB columns in the database. As the
persistent structure of these classes changes, action may be required to maintain
compatibility with previous versions that have been serialized into the database.
During the migration period (that is, at Windchill Release 4.0), all Externalizable
classes have the methods necessary to manage class compatibility but, in the
future, only Evolvable classes will have these features. Any modeled class that is
intended to support being serialized into a BLOB database column must
implement the Evolvable interface. Once Evolvable is implemented, the owner of
the class must manage its compatibility from version to version.
The Persistent Data Service (PDS) will report any classes being serialized into the
database that implement the NetFactor interface and not the Evolvable interface.
This allows third party classes, such as Vectors, Hashtables, and so on, to be
serialized into the database. This also allows modeled classes that do not
implement NetFactor to be serialized into the database; however, we do not
recommend this practice because it leaves the class exposed to serious data
migration problems.
The best way to specify that a modeled class will implement the Evolvable
interface is to set the Serializable property for the class to Evolvable. This
property is on the Windchill tab of the class specification in Rose.
/* 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
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();
a2 = (Date)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
Topic Page
Creating Large Objects (LOBs) ........................................................................44-2
44-1
Creating Large Objects (LOBs)
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 );
// save a LOB of known length
len = lobFile.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 {
if ( trx != null ) {
trx.rollback();
throw new RuntimeException("Error
processing lobs");
}
}
}
}
}
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
Topic Page
Adding and Updating Data Formats for Content Holders.................................45-2
45-1
Adding and Updating Data Formats for Content Holders
When content files are added to a content holder object, the format of the file
(based on the file name extension) is set automatically upon upload. The available
formats are stored as DataFormat objects in the system.
In some cases, you may need to augment or change the existing data formats to
accommodate additional MIME types associated with your enterprise data.
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 Solution Name, to maintain data
format objects.
You are then prompted to provide values for the following attributes:
Attribute Description
Format name (required) Displays this name (for example, Microsoft Word) in the client to
identify the file format. The value specified must be unique.
MIME type (required) The MIME type (for example, application/msword) to be used in
downloading a file of this type. You must specify a space-separated
list of valid extensions for the MIME type (for example, .txt, .text, or
.t). This is the way in which the format of these objects will be set
when a file is uploaded.
Indexable (required) Indicates whether or not this data format type can be indexed. Most
MIME types supported are defined in the system when it is installed.
However, any simple text format is indexable.
Icon (required) Defines the path to a subdirectory of the codebase that contains the
icon for this format type. When you add a data format type, you have
the option to reference an icon other than one of those found in the
Solution Name codebase. However, you must ensure that the pixel
size for your icon is 16 x 16 to avoid an error when viewing icons.
Extensions (required) Defines the extensions that are associated with this particular mime
type (for example, .doc or .rtf for Microsoft Word).
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.rbinfo file and then
run the ResourceBuild utility to generate resource classes from
FormatNameRB.rbinfo file. Enter the new line using the following format:
<Mime_Type>.value=<Display_Value>
For example, if the MIME type is Java Archive and display value desired is Java
Archive File, then new entry is as follows:
Java Archive.value=Java Archive File
For details on using the ResourceBuild utility, see the System Generation chapter
on page 32-1.
The tool prompts you for the format name of an existing data format object. After
you have identified the data format, you can update its attributes.
If you make a change to the MIME type name or display value, you must also
update the corresponding line in the wt\content\FormatNameRB.rbinfo file.
Note: If you change the MIME type of a data format object, you must stop and
restart the method server to implement the change.
The tool prompts for the format name of an existing data format object. After the
data format is identified, it gets deleted. If any object currently refers to this data
format, then data format is not deleted and error is shown.
Chapter Page
Extendable Classes in the Windchill Supported API............................ A-1
Multi-Object Conversion Guidelines .................................................... B-1
Creating Non-Modeled Services for Listening ..................................... C-1
Windchill Profiler ................................................................................. D-1
Additional Topics - Client Customization .............................................E-1
A
Extendable Classes in the
Windchill Supported API
This appendix lists many of the extendable classes and implementable interfaces
in the Windchill supported API. It serves as a roadmap to help guide developers
when initiating modeling activities. Further information about these classes can be
found throughout this manual, and in the Windchill Javadoc.
Many Windchill objects and features can be tailored without programmatic
customization. For more information on these options, see the Customization
Overview on page 1-1. Additional information can also be found in the Windchill
System Administrator's Guide, and the Windchill Business Administrator's Guide.
Topic Page
PDM Business Information Classes ...................................................................A-2
Enterprise Business Information Classes ...........................................................A-2
Windchill Services .............................................................................................A-2
Foundation Classes.............................................................................................A-3
PDM Auxiliary Business Information Classes...................................................A-3
Business Logic Classes ......................................................................................A-3
Server Development Classes ..............................................................................A-4
Client Development Classes...............................................................................A-5
A-1
PDM Business Information Classes
Following are the starting points for extending PDM objects (part, document, and
change objects). If you want to extend the behavior of the Windchill out-of-the-
box PDM objects, start by extending these classes. For an overview of these
classes, see the The Enterprise Layer chapter on page 37-1.
wt.change2.WTAnalysisActivity
wt.change2.WTChangeActivity2
wt.change2.WTChangeInvestigation
wt.change2.WTChangeIssue
wt.change2.WTChangeProposal
wt.change2.WTChangeRequest2
wt.doc.WTDocument
wt.doc.WTDocumentMaster
wt.part.WTPart
wt.part.WTPartMaster
Windchill Services
The following extendable classes represent the Windchill plug-and-play
interfaces. For more information, see the Windchill Services chapter on page
31-1.
wt.change2.Changeable2
wt.content.ContentHolder
wt.content.FormatContentHolder
wt.folder.Foldered
wt.folder.IteratedFoldered
wt.index.Indexable
wt.locks.Lockable
wt.ownership.Ownable
wt.vc.baseline.Baselineable
wt.vc.Iterated
wt.vc.Mastered
wt.vc.Versioned
wt.vc.views.ViewManageable
wt.vc.wip.Workable
Topic Page
Conversion Overview......................................................................................... B-2
API Guidelines ................................................................................................... B-3
Collections Guidelines ....................................................................................... B-7
Event Dispatch Guidelines ................................................................................. B-9
Multi-Object Delegation Guidelines ................................................................ B-10
Multi-Object Exceptions Guidelines ................................................................ B-11
Multi-Object CRUD API Guidelines ............................................................... B-13
Batch Update/Delete Guidelines ...................................................................... B-13
Transaction Context/Listener Guidelines......................................................... B-14
Neat Tips and Tricks ........................................................................................ B-15
B-1
Conversion Overview
Objectives
Windchill performance is largely a function of database access: how often you go
to the database, what you send it, what you ask it to do, and what you ask it to
send back to you.The primary goal of converting single-object APIs to multi-
object is to replace the CRUD operations driven by single objects with multi-
object CRUD operations.
A single-object operation that does a query and then updates, individually, the
objects returned by that query will execute n queries and as many updates as the
number of objects those queries produce. Ideally, the multi-object conversion of
that operation will execute one query and one update. While what is being sent to
the database, asked of the database, and sent back from the database is about the
same, the number of trips has been significantly reduced. Since the “connection”
cost is significant (and, furthermore, since the CRUD operations take advantage
of more performant batch SQL operations), the multi-object will significantly
outperform the looped-over single-object operation. This is true even before the
VM cost of the looping is factored in.
Considerations
The following factors weigh in to increase the complexity of multi-object
operations over their single-object counterparts:
• What should the multi-object operation's signature look like?
• Exceptions?
• Related data changing?
• Data coming at you for different reasons?
• Complex query building?
The first API requires that all of the objects in the set go to the new folder and
represents a simple multi-object API that would require the caller to call the API
multiple times if changes to multiple folders are required.
The second API simply maps the foldered object to the new folder to change to; it
(the multi-multi-object API) is more complex – there's a lot more to manage in the
API and the caller is required to build the map even if all of the objects are going
to a single location. If the second implementation requires an internal breakup by
folder, it'll likely not be appreciably more performant than the former. Then again,
if it doesn't need to break up the data and can dispatch a single event for all the
moved objects, it will likely be more performant, although the added complexity
will then be passed onto the multi-object listeners.
If performance is the only measurement, the multi-multi-object API wins.
However, there are other factors to consider:
• When weighing the performance benefits, is it really the case that in the API
(and in any of the listeners for the events the API might dispatch) the code
won't simply end up breaking up the work in such a way that it's really
looping over the work as though it were multi-object and not multi-multi-
object?
• Is there a real need to provide that flexibility?
• Is the additional flexibility worth the additional complexity?
• If more than a map is needed, multiple, ordered arguments grouped by index
is probably the only way to pass the data, but this is somewhat ugly. For
example, checkout takes a Workable to check out, a folder to check out to,
and a note representing the check out comment; making all three arguments
multi-object most likely implies two lists and an array, or three lists.
Note: The changeFolder APIs in the Folder Service are not intended to be used
when moving Foldered objects between containers; the moveAllVersions API in
the Container Move Service should be used instead.
Empty collections
Windchill does not have a prescribed standard for the validation of arguments to a
method. Some methods exhaustively validate each argument, others leave invalid
arguments to fail later in the method (via NullPointerExceptions and the like).
The issue of argument validation comes up in collections not because they might
be null, but because “transformation ” operations (sub-collections, conditional
copying of collection elements, etc.) may result in a collection being empty. That
empty collection, then, may be passed to another multi-object API. What would it
mean to call “store ” with an empty collection? What should the store method do?
There are a few options relative to this:
• The method checks if the collection argument is empty; if it is empty, it
throws an IllegalArgumentException
Memory considerations
A multi-object operation has a much higher footprint than the corresponding
single object operation. This is true in both the VM, where multi-object operations
take significantly more memory, and in the database, where transaction sizes
increase dramatically.
There are some things that can be done to the reduce memory footprint, such as
querying only what is needed to make decisions. Both the VM and Oracle can be
tuned to handle the expected increased footprints.
Inflating
The WTCollection interface transparently masks the fact that a persistable can be
represented as a QueryKey, WTReference, or full-blown Persistable. It also has
iterator APIs (queryKeyIterator(), referenceIterator(), and persistableIterator()) to
get the objects based on the representation desired. The persistableIterator() will
inflate the query keys and references if they are ot already inflated, but it is
important to note that referenceIterator will not. This means that one should be
extremely careful using the following code:
for (Iterator i =col.referenceIterator();i.hasNext();){
...
Persistable p =((WTReference)i.next()).getObject();
...
}
The problem with the above code is that the getObject() may result in sequential
inflates. Unless you're absolutely sure the collection has bee inflated, this is a bad
idea. Even if you are, it's a bad idea. Instead, use the persistableIterator()API.
Using connect()
WTCollection's inflate and refresh implementation does not replace persistables
in-place. This means that two collections with the same data may become out-of-
sync when an inflate or refresh is done on one of the collections.
When creating new collections from the objects in existing collections, use the
connect() APIs to ensure that the changes made to objects in one collection affect
all the collections which contain the same objects.
WTKeyedMap vs.WTValuedMap
The WTKeyedMap is a map in which the keySet is essentially a WTCollection,
providing all of the benefits of the WTCollection to the keys. The values,
however, are just a regular collection. Many APIs will wish to map Persistables as
keys to Persistables as values, which is exactly what the WTValuedMap provides;
the WTValuedMap's values are a WTCollection.
Where both the keys and the values are Persistables, the WTValuedMap should be
used.
Modifying collections
Generally, the contents of collections passed to an operation as argument should
not be altered (by removing or adding members); doing so alters the caller's
collection. Be especially careful using collections' APIs that produced
“backed”collections, such as the “subCollection(...)” APIs, as modifying the
contents of a backed collection also change the contents of the source collection.
Cleanup
Many of the single-object events could benefit from cleanup work. For exampole,
a lot of them include the service, which is of dubious utility. Many have odd
datatypes, such as paired vectors. When converting these events to multi-object,
how much of this should be cleaned up? Should the multi-object variant, for
example, include the service? Should the service be removed from the single
object event? Should more of the single object be cleaned up? When considering
how much to do, consider also the following:
• The ultimate goal is to totally replace the single-object variant by converting
all the listeners to multi-object, so it may not make much sense to spend
significant time cleaning up the single-object events
• Cleanup of the single-object events beyond that of removing the service will
likely require reworking existing listeners, taking time from the more
interesting tasks of making those listeners multi-object
In general, little should be done to the single-object events save superficial clean
up (such as removing the service). An exception to this is when the changes to the
event to make it multi-object necessitate a re-evaluation of the single-object event.
Use of collections
The multi-object events, like other multi-object operations, should pass
collections of objects. These collections should be unmodifiable to ensure that
listeners and the APIs they call do not alter the contents of the collection.This
deviates slightly from the relaxed stance taken above, however there is never
justification for a listener to alter an event's contents, so it should be ensured that
this does not happen.
Converting to wt.services.ac.DefaultServices
There are numerous patterns for delegation in place today. Wherever possible and
practical, these patterns should be replaced by the use of
wt.services.ac.DefaultServices. This single class and its static APIs eliminate the
need to do things like implement interfaces such as ApplicationContextChild. As
with other "cleanup work" associated with converting to multi-object, actually
cleaning up delegation in code should be weighed against the cost of cleanup.
Basic expectations
Multi-object operations can detect multiple failures.The simplest example of this
is the query that, if results are found, indicates an error condition. The conversion
to multi-object implies that multiple rows may be returned by such a query.
Should a single-object exception be thrown against the first result or a multi-
object exception against the entire result? More generally, how far should one go
in reporting exception conditions to the user?
The first, absolute rule is that if a exception is thrown to you, you are done. You
should not be continuing after an exception has been thrown because an exception
corresponds to a non-local exit, which means that the operation did not finish its
normal processing and work was not completed. Not to mention that, oftentimes,
the operation, as part of a finally block, will rollback the transaction.
This document suggests a “throw what you know ” approach to exceptions. Use
the additionalMessages capabilities of the multi-object exceptions when you
have additional knowledge. With the example above, it would make sense to build
a multi-object exception out of all of the results.
Another common example is that of validation in a loop. Say that code is
processing the collection in a loop and would throw an exception if the value of a
field is invalid. Should this code collect all the failures and throw a multi-object
exception at the end of the loop, or should it throw a single-object exception
immediately? In most cases, the code should collect the messages for the failures
and throw a multi-object exception at the end of the loop.
Pre-flight checks
The single-object APIs all “fail fast” -- once an error condition is discovered,
processing stops and an exception is thrown. For example, if it is determined that
the object a user wants to check out is already checked out, the code doesn't
continue determining if the user does or does not have modify access; it bails out
and throws an exception.
Many single-object APIs, and by extension their multi-object counterparts,
perform what are called “pre-flight checks ”. These are the validations that occur
before the real work is done to the object(s). The single-object APIs bail when the
first validation fails.
With multi-object operations, however, it is possible to take the another approach.
Upon encountering an error, they may continue to collect additional problems so
as to later report a more informative exception message. Thus, the multi-object
check out operation could check access (provided it uses the non-exception
throwing “hasAccess ”), validate that the objects aren't already checked out, and
do a number of other things, recording the problems along the way, and eventually
throw a single exception with messages for each of the failures. The motivation to
do this is the belief that it will aid the users, as they will get as much information
When to Use?
The batch update/delete operations represent the most performant option for
affecting change in the database because they minimize both the data needed to
perform the operation and the data eeded to affect the change – neither requires
that the objects to be changed first be retrieved from the database and only the
columns to change need to be sent (as opposed to full persistables) in the case of a
update. These APIs should be considered when:
• There is no need to bring the object back into the VM, either to perform tests
or to dispatch events
• None of the objects involved in the batch operation exist in memory prior to
the batch operation
In most cases, it is sufficient to say that their use should be limited only to cases
where there is never a need to bring the object (or its reference) back to memory
and should never be used on objects already in memory. The above guidelines are
based on the fact that the performance benefits drop when the data is actually
needed and by the fact that the changes will not be reflected in any of the in-
memory objects. However, a gray area for batch update is in cases where the
references are needed for event dispatch, the dispatched event indicates that the
change has occurred, and the listeners need not inflate.
Single-object contexts
Existing single-object code that puts objects on the method context for
downstream processing will need to be evaluated. Both the code that puts the
object on the context and the code that processes it will likely need to change. In
fact, only when the downstream consumer of the context data is guaranteed to still
be flat-lined (from the point that the flat-lined code added the context) will the
single-object context be OK.
The issue, especially in the case of contexts added by listeners, is that the
downstream code may be dealing with the entire collection while only a single
object is on the context. Keep in mind that the dispatch order is multi0-ab,
single0-a, single0-b, multi1ab, single1-a, single1-b, NOT multi0-ab, multi1-ab,
single0-a, single1-a, single0-b, single1-b, so if one listener, in single-object mode,
adds an object to the context for another listener to consume, the other listener
will always only get the last object in the collection on the context because event
dispatch will loop over the first listener (single0-a, single0-b) before getting to the
second one (single1).
Inflating references
If you have a collection of objects with references you wish to inflate, simply add
the references to a new collection and inflate it. Since the inflated objects are set
in the existing references, this will result in the original object's references getting
inflated.
The master references in the parts will automatically reflect the persisted changes
of the partMasterCollection (most notably, the OIDs will now be in the references.
Topic Page
Overview ............................................................................................................ C-2
Create a Service Interface................................................................................... C-2
Create a Standard Service Class......................................................................... C-3
Compile .............................................................................................................. C-5
Register the New Service ................................................................................... C-6
Restart the Method Server.................................................................................. C-6
C-1
Overview
Customers that do not have Windchill InfoModeler may create services for
listening to events generated by other services (customers that have Windchill
InfoModeler 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 chapter on page 36-1.That chapter explains how to write code to
register listeners for particular events.
The example below has comments that indicate "standard" pieces of code that
should not be changed as they are necessary to interact with the standard service
manager and other services. There are other comments that indicate pieces of
code that should be changed, for example, to reflect your choice of package and
class names and to listen to the particular events you are interested in.
Here is the source code:
/* Change to your package name */
package com.acme.listen;
import java.lang.String;
/**
* Listens for pre/post checkin events. When an event is
* "heard", prints messages to the MethodServer log and console.
* <p>
* Use the <code>newStandardListenService</code> static factory method(s),
* not the <code>StandardListenService</code> constructor, to construct
* instances of this class. Instances must be constructed using the static
* factory(s), in order to ensure proper initialization of the instance.
* <p>
*
/*
* Standard default factory for the class.
*
*/
/*
* Initializations of event listeners
*/
getManagerService().addEventListener(
new ServiceEventListenerAdapter( this.getConceptualClassname() ) {
public void notifyVetoableEvent( Object event )
throws WTException {
final Workable target =
((WorkInProgressServiceEvent)event).getOriginalCopy();
System.out.println("Listen hears POST_CHECKIN: ");
System.out.print(" target:");
System.out.println(target.toString());
}
},
WorkInProgressServiceEvent.generateEventKey(
WorkInProgressServiceEvent.POST_CHECKIN ));
Compile
Compile your classes into:
<Windchill>/codebase/com/acme/listen
Note that xconfmanager will add the entry to site.xconf and then propagate the
changes to wt.properties.
The Windchill Profiler can be used to help diagnose performance bottlenecks after
you have customized code. It enables you to capture an elapsed time profile while
executing application logic in the method server. The profile shows call stacks,
call counts, and context data (for example, SQL, bind parameters, JNDI strings,
son on). PTC recommends profiling in a test environment; however, profiling is
possible in a production environment without interrupting system operation.
Topic Page
Overview ............................................................................................................D-2
Profiler Features .................................................................................................D-2
Profiler Operation...............................................................................................D-2
D-1
Overview
The Windchill Profiler enables you to instrument server side application logic. A
user interface is provided to control the profiler, which is embedded within the
method server.
Note: Support for the profiler is limited and the profiler is subject to change
without notice.
Profiler Features
The Windchill Profiler supports the collection of performance profiles in the
following Windchill subsystems:
• JDBC execution
• CacheManager get/put/update
• WTAdapter JNDI Task
• RMI Object Serialization
The profiler allows you to filter call stacks by thread; sort call stacks by count or
by cost (for example, elapsed time). The call stacks, call counts, and elapsed times
are displayed in a JTree format. The output can include additional data such as
SQL bind parameters or cache keys.
Profiles can be saved to disk and reloaded, or they can be exchanged using e-mail.
HTML summaries can also be generated.
Profiler Operation
To launch the profiler, open a command shell on the Windchill server. From the
windchill shell, invoke the profiler as follows:
windchill wt.tools.profiler.WindchillProfiler
Note: A long running profile session might need a larger heap. In that case, use
the following command to start the profiler:
windchill --javaargs=-Xmx512m
wt.tools.profiler.WindchillProfiler
Call stacks appearing in the right pane need to be expanded until the leaf node for
a given call stack is displayed. The leaf node of a call stack contains an SQL
string.
Topic Page
Defining Non-JSP Actions to be Executed From a JSP Page ........................... E-2
URLFactory in the JSP Environment................................................................. E-5
Using File-Handling Applets in Non-JSP Clients............................................ E-14
E-1
Defining Non-JSP Actions to be Executed From a JSP Page
Actions that will be executed from a page built using the Windchill JSP
framework must be defined in the file <Windchill>/codebase/actions.xml.
Each object type needs a defined element (i.e., using <objecttype></objecttype>).
Within this element is entered each of the actions that may be available for this
type of object. The name specified for this element is used as an alias for a fully
qualified class name. The class attribute is the fully qualified class name for the
object type.
The files <Windchill>/codebase/action_*.properties are complementary to
actions.xml, containing entries for things such as labels, tooltips, and icons to use
for the actions based on a certain locale.
Below is a snippet from the actions.xml file used in R7.0. These actions are used
for the Site tab and its sub-tabs.
<objecttype name="site" class="com.ptc.netmarkets.site">
<action name="view" checkaccess="true" enabledwhensuspended="true">
<command windowType="page"/>
</action>
<action name="listOrgs" checkaccess="true" enabledwhensuspended="true">
<command windowType="page"/>
</action>
<action name="listFiles" checkaccess="true" enabledwhensuspended="true">
<command windowType="page"/>
</action>
<action name="listAdmin" enabledwhensuspended="true">
<command windowType="page"/>
</action>
<action name="listTypes" enabledwhensuspended="true">
<command windowType="page"/>
</action>
<action name="listTemplates" enabledwhensuspended="true">
<command windowType="page"/>
</action>
<action name="listUtilities" enabledwhensuspended="true">
<command windowType="page"/>
</action>
<action name="site_audit_Reports" enabledwhensuspended="true">
<command windowType="page"/>
</action>
</objecttype>
where <type> and <action> are, respectively, the names of the objecttype and
action specified in actions.xml.
If you want to override this default you can specify a value of GENERAL,
GENERAL_WITH _CONTEXT, or PDM for the renderType on the action.
with
<Windchill>/codebase/wtcore/jsp/customizedAction.jsp
actions.xml Elements
Listed in the following table are the valid elements and their attributes that can be
used to register an action.
Creating an URLFactory
All Windchill Java client Server Pages or Servlets should set the context by using
the WTContextBean using the code below:
<% [ ] /*** The WTContextBean is a JavaBean for use in
Java Server
Pages or Servlets that wish to use Windchill Java client
or server
APIs ***/ % [ ]> <jsp:useBean id="wtcontext"
class="wt.httpgw.WTContextBean" scope="request"
<jsp:setProperty name="wtcontext" property="request"
value="<% [ ]=request% [ ]>"/> </jsp:useBean>
Next, an URLFactory instance may be created for the current codebase by using
the useBean JSP command and setting the scope of the URLFactory (in this case
for the request, which supports JSP include commands).
<% [ ] /*** The URLFactory is a JavaBean for use in the
generation of HREFs used in Windchill HTML clients ***/ % [ ]>
<jsp:useBean id="url_factory" class="wt.httpgw.URLFactory"
scope="request" />
If a remote codebase needs to be accessed (note the request from the server) an
URLFactory object can be instantiated by first creating the bean as above, and
then recreating the URLFactory pointing it to the new codebase. (NOTE: The
codebase ends with a ’/’ marking it as a directory.)
<% [ ] /*** The URLFactory is a JavaBean for use in the
generation of HREFs used in Windchill HTML clients ***/ % [ ]>
<jsp:useBean id="url_factory" class="wt.httpgw.URLFactory"
scope="request" > <% [ ] url_factory = new wt.httpgw.URLFactory
( SomeURLToRemoteWindchill );
% [ ]> </jsp:useBean>
Setting a BaseTag
This configuration has the advantage of allowing a user to reload a page after it
has been persisted (say to a local file system) and still have all the links work
properly. If the base is to be the Windchill Codebase then a call to
setRequestURItoBase() will suffice.
<BASE HREF="<% [ ]= url_factory.setRequestURItoBase() % [ ]>">
However in many situations, you may wish to set the base tag relative to some
point in the Windchill codebase. An example is you want to generate a search
page and have all the links be relative to some starting position. In this case, a
little more is involved. If you can obtain the current request context (i.e., you are
developing either a jsp or servlet page) then first you should set the request
information using the setRequestURL() method described above.
Setting the BaseTag Within a Non-JSP Page or Servlet (i.e, Java code)
We will not have access to the request object in Java code that is not a servlet.
Therefore we have to set the RequestURI to be relative to initially the Windchill
codebase based on the configured host, protocol and port information and then set
the requestURI to desired resource.
...
// Set the request URI to the Windchill codebase.
url_factory.setRequestURItoBase();
// Now set the request URI to the desired resource.
url_factory.setRequestURI("wt/clients/login/Login.html");
// Now we can obtain the string for the Base Tag
String baseTag = url_factory.getFullyQualifiedRequestURI();
Depending on the Request Context setup above, the correct HREF String will be
returned and inserted into the output page at compile time.
Forcing a Fully Qualified Link With a URLFactory that has a Non-null Request URI
If you want to create a link that opens a file in a new window (such as through the
Javascript.open( ) method) the string must be fully qualified. However, the rest of
the links on the page may be relative.
Most getHREF() methods have a form which accepts a boolean. By using this
form, it is possible to request a fully-qualified URL from a URLFactory which is
otherwise configured to generate relative URLs.
<A HREF="<% [ ]= url_factory.getHREF( "wt/clients/login/Login.html"
, true ) % [ ]>">Fully Qualified Link</A>
2. Set the response content type. This will set the encoding of the HTML page
returned to the client. It should be set near the start of the JSP page (after Bean
declarations). In order to do this the following needs to be added:
<% [ ] response.setContentType( "text/html; charset=UTF-8" ); %
[ ]>
Note: The response content type method must be called before any call to
request.getParameter() is made.
EncodingConverter
Note: See the EncodingConverter class entry in your installed Windchill Javadoc
for more information.
The second method that can be to used is the parseQueryString() method of the
URLFactory() class. Usage of the parseQueryString() method takes an encoded
query string and decodes it. The result is placed into a HashMap. The HashMap
values may then be queried using the HashMap ’get’ method. This method will
only work with Request Parameters and not form elements. For example:
// Use the URLFactory to parse the Query String
//
java.util.HashMap query_map =
url_factory.parseQueryString(
request.getQueryString() );
// Retrieve the (already decoded) string
from the hash map
//
String tag = query_map.get("tag");
Deprecation of WTURLEncoder
As of Windchill release 6.0 WTURLEncoder SHOULD NOT be used for text
encoding or decoding. This class may be removed post-R 6.0.
Encoding of Forms
By default POST submitted forms are submitted using the encoding application/x-
www-form-urlencoded. The methods provided above for decoding the text will
allow these form’s data to be written properly.
All HREFs and URLs should be generated using the URLFactory class. The
URLFactory provides methods to automatically encode any non-ASCII characters
in the query string, if a HashMap containing the parameters is provided to the
URLFactory. If a string is being passed in for a query string that has been created
within your code, you must encode it first, with a call to
EncodingConverter.encode()
Note: See the URLFactory class entry in your installed Windchill Javadoc for
more information.
<% [ ]
// Set the content type for the response
response.setContentType("text/html; charset=UTF-8");
// Get the current locale for the browser that is supported by Windchill
// This to used with WTMessage.getLocalizedMessage(RESOURCE,"tagname",locale)
java.util.Locale locale = wt.httpgw.LanguagePreference.getLocale(
request.getHeader("Accept-Language") );
% [ ]>
</HEAD>
<BODY>
<h1>Sample Form</H1>
<% [ ]
String text = request.getParameter("sample_text");
if ( text != null )
{
% [ ]>
File Selection
There are two ways to choose one or more files for upload in Windchill.
1. File Browse: Launch a file browser from the Windchill UI and navigate to the
desired file(s).
2. Drag-and-Drop: Drag one or more file icons from the desktop or Windows
Explorer onto a drop target in the Windchill UI.
Button look:
<param name="buttonLook" value="true">
The "hyperlink with icon" look is typically used in a multi-select situation where
each selected file will result in another row added to a table.
Drag-and-Drop targets
The presence/absence of a file drop target next to the file browse launcher is
determined by the following parameter (true means drop target, false means no
drop target):
<param name="acceptFileDrop" value="true">
When using a drop target, you will need to provide a pair of images to use for the
drop target's normal state and active (dragged-over) state.
The following images are provided by Windchill for this purpose:
Normal:
<Windchill>/codebase/wtcore/images/droptarget.gif
function setPathFromApplet(newValue,fileSep,pathComplete) {
appletString = appletString + newValue;
if ( pathComplete != null && pathComplete == "true" ) {
window.focus();
var endPos = newValue.indexOf( DELIM, 0 );
if ( endPos >= 0 ) {
wfalert( tooManyFilesDroppedMsg );
} else {
setPath(CheckFilePathSeparators(appletString,fileSep));
}
appletString = "";
}
}
function setPath(newValue,fileSep,pathComplete) {
appletString = appletString + newValue;
if ( pathComplete != null && pathComplete == "true" ) {
window.focus();
submitNewAttachments(CheckFilePathSeparators(appletString,fileSep) );
appletString = "";
}
}
buttonLabel "Browse... ", "Add Attachments... ", "Add Files... Label for button or "hyperlink"
" seen in HTML page
actionLabel "Open", "Choose File", "Select Attachments" (Optional) Label for window and
action button on file browser dialog
If the file is invalid and the preferences and/or user prompt do not authorize
skipping the upload, or if the file is valid but the upload is unsuccessful, or if the
user cancels, then the applet will forward to the "failureUrl" and/or
"failureJSMethod" (if both are provided, failureUrl will be passed into
failureJSMethod as an argument value). This typically displays some sort of error
feedback message (unless cancelled) and returns to the form where the primary
filepath was originally selected.
When performing a multiple-file upload, such as multiple primary files or
attachments, individual feedback is not provided on each file. Instead, all valid
files are uploaded and a list of all invalid filepaths is compiled. When the upload
is complete, this list of invalid filepaths is sent as an argument to a designated
Javascript method, along with the appropriate URL. When uploading multiple
primary files, this will always be the Javascript method and URL specified in the
applet parameters for the completion case. When uploading secondary files, the
method and URL may be from either the completion or failure cases, depending
on the outcome of the selected primary content file upload.
Note: This Javascript assumes the existence of a hidden HTML form in the page
named <form name>, containing named hidden fields <checksum form field
name> and <uploadFeedback form field name>. The real names of this form and
these fields should be substituted into this Javascript before use.
<SCRIPT language=javascript>
if ( !cancelled ) {
alert( uploadFailureMessage );
}
</SCRIPT>
debug true, false (Optional) Defaults to false, change to true for Java
Console output during processing
A Best practices
modifying files, 5-9
Access control new files, 5-26
Property, 2-12 Bill of Materials
Access control package, 31-5 Customizing, 22-19
Accessor methods Hierarchy Visitor, 22-20
Overriding, 36-9 product structure, 22-19
Adding report, 22-19
content holder data formats, 45-2 bin directory, 2-2
API BOM
report generation, 28-31 see Bill of Materials
Applet Business Classes, 22-2
Advantages, E-14 Business classes
Content Download Applet, E-14 Revision controlled business class, 37-6
Content Upload Applet, E-14 Business data types
Default Local Directory, E-18 Implementing, 36-8
Disadvantages, E-14 Business objects
Download Applet, E-41 Modeling, 4-1
Download Applet Parameters, E-43 Business services
File Selection Applet, E-14 Implementing, 36-14
File Selection files for upload, E-15
FileChooserDropAppletParameters, E-19 C
FileChooserDropAppletsample HTML, E-20
Multi-Select Javascript sample, E-18 cat files, 2-7
Processing File Selection Output, E-17 For sharing code, 2-8
Sample Javascript for Feedback and Navigation, Change Management Delegates, 23-2
E-24 ChooseFolderDelegate, 23-2
Single-Select Javascript sample, E-17 ChooseLifeCycleDelegate, 23-2
Upload Applet Parameters, E-28 ConcreteAssociationDelegate, 23-3
Upload Behavior-System Properties, E-26 DisplayIdentificationDelegate, 23-4
Upload Behavior-User Preferences, E-27 Change Management Workflow Process Templates
UploadApplet, E-22 Change Issue Process, 25-6
Audit Event Code Impacted, 25-12
configaudit.xml file, 29-7 Custom Workflow Process Templates, 25-12
Handler Classes, 29-7 customizing, 25-6
ProjectAuditEvent, 29-4 Existing Installations, 25-11
Audit Recorders, 29-7 Installation and Upgrade, 25-11
auditing events New Installations, 25-11
configuration file, 29-3 Synch on Change Request Submit, 25-8
Windchill Auditing Framework, 29-2 Synch on Multiple Object State Change, 25-10
synchronization robots, 25-6
B checkAttribute method, 36-12
ChooseFolderDelegate, 23-2
Batch scripts, 2-2 ChooseLifeCycleDelegate, 23-2
Index-1
Class files, 2-5 overriding, 21-9
Class path environment variable, 2-9 Customized files, 5-2
Classes Customizing, 28-16
Document, 37-10 Customizing Modeled Business Objects
Folder resident business class, 37-4 Windchill Customization Points, 1-8
Foundation classes, 4-10 Customizing workflows
Item, 4-10 key points, 25-14
Link, 4-11 lock/unlock promotion targets, 25-14
Managed business class, 37-5 owner role, 25-16
Part, 37-13 review promotion request activity, 25-15
Simple business class, 37-2
WTObject, 4-10 D
ClassInfo.ser files
Location, 2-6, 2-13 Data Model Customizations, 1-5
CLASSPATH environment variable, 2-9 Database
Client JAR files, 5-7, 5-11, 5-14 Access set by properties, 2-14
Code db.properties.file, 2-14
Sharing, 2-8 Default table size, 2-13
Code generation Properties file, 2-3
Files, 2-7 Property file
See system generation See db.properties file
tools.properties file, 2-13 Database indexes, 22-12
Code Impacted db directory, 2-3
Change Management Workflow Process Tem- db.properties file
plates, 25-12 Database access properties, 2-14
codebase directory General description, 2-10
Details, 2-5 wt.pom.dbPassword property, 2-14
Location, 2-3 wt.pom.dbUser property, 2-14
codebase files, 5-13 wt.pom.serviceName property, 2-14
Column Length Debug tracing, 2-12
change for modeled attribute, 33-2 debug.properties file
customizing, 33-2 General description, 2-10
default location, 33-2 Default Local Directory, E-18
comment defaultValue
EnumeratedType, 34-2 EnumeratedType, 34-2
CompositeUnique property, 22-13 Design Pattern
ConcreteAssociationDelegate, 23-3 Business Service, 35-3
constantEnumeratedType, 34-6 cookie abstraction, 35-4
Content Download Applet, E-14 helper abstraction, 35-4
Content holders service abstraction, 35-5
data formats, 45-2 ServiceEvent abstraction, 35-5
Content Upload Applet, E-14 ServiceException abstraction, 35-6
Control units, 2-8 type abstraction, 35-4
cookie abstraction Iterated interface, 35-7
Design Pattern, 35-4 Master Iteration, 35-7
createSafeArea target, 5-6 Mastered interface, 35-7
Creating new packages, 5-26 Object Reference, 35-2
CSS Customization, 28-17 Development environment
csvReport Template, 28-11 Directory structure, 2-2
elements, 28-11 Environment variables, 2-9
Custom Reports, 1-6 Files, 2-3, 2-7
custom_getFieldData Property files, 2-10
Index-3
Design Pattern, 35-4 L
HTML files
Location of, 2-6 Link class, 4-11
HTML templates, 5-12 listSiteChanges target, 5-6, 5-8
listSiteChangesIgnored target, 5-6
I listSiteModExclusions target, 5-6
loadFiles directory, 2-3
IdentificationObject, 22-6, 22-8 Loading
implements identified, 22-8 Initial data, 2-3
implements UniquelyIdentified, 22-10 LoadReport Template, 28-11
Identified, 22-7 standalone mode options, 28-13
Identity Attributes Localization, 40-1
flowchart, 22-5 Location of required files, 2-6
IdentityService, 22-5 Localizing
modify, 22-2 Text, 40-5
RevisionControlled Identity, 22-4 Logging
SemanticKeys, 22-11 Default location for trace logs, 2-3
System Assigned, 22-2 Enable/disable logging, 2-12
UniquelyIdentified, 22-11 Trace messages
User-Assigned, 22-2 From method server, 2-12
Identity attributes, 22-2 From server manager, 2-12
IdentityService LogicalAttributes.xml file, 5-12
How to use, 22-6 logs directory, 2-3
Implementation of Visitors, 22-22
quantity units, 22-22 M
Indexed-Search webject
customized search application, 21-2 Macros
IndexObject method reference, 21-10 customizing, 28-35
IndexSearch report parameter, 28-9
indexed text, 21-6 make_jar.config_jars target, 5-7
Info*Engine, 1-6 Managed business class, 37-5
Info*Engine tasks, 5-13 Managing client JAR files, 5-14
INI files, 5-13 mData files, 2-7
Installation and Upgrade Location, 2-13
Change Management Workflow Process Tem- mdl files, 2-7
plates, 25-11 Meetings, 30-2
installSiteChanges target, 5-6, 5-8 Method server
Internationalization, 40-1 Logging trace messages, 2-12
Item class, 4-10 Model files, 2-7
Iteration and Version Identifiers Modeled
Customizing, 22-17 PSE Support, 20-5
multicharacter series, 22-18 Modeling
Iteration Identifiers Business objects, 4-1
integer series, 22-17 Modifying files, 5-9
Multicharacter Series, 22-18
J MyDerivedItem
enumerated type, 34-10
java.rmi.server.hostname property, 2-12 MyDerivedSize
java.util.Date, 28-29 enumerated type, 34-10
Javascript method MySize
File Selection Applet, E-17 enumerated type, 34-10
Packages R
Access control, 31-5
Control units, 2-8 Rational Rose, 4-2
Doc, 37-10 Virtual path map, 2-9
Document, 37-10 Windchill extensions, 2-9
Enterprise, 37-2 WT_EXTENSIONS entry, 2-9
Location, 2-6 WT_STD_PACKAGES entry, 2-9
Overview, 31-2 WT_WORK entry, 2-9, 2-13
Part, 37-13 Rational Rose Modeler Edition, 5-27
Query, 38-4 RB.java files
Packages, new, 5-26 Location, 2-6
Parameters RB.rbInfo
Input to the webject, 21-2 enumerated type, 34-7
report generation, 28-7 RBINFO files, 5-9, 5-10
Part class, 37-13 Rebuilding client JAR files, 5-7, 5-11
Part package, 37-13 Report Generation
PATH environment variable, 2-9 API, 28-31
Path environment variable, 2-9 basic example, 28-2
Persistence client, 28-30
Management, 38-1 csvReport Template, 28-11
Manager, 38-2 customization details, 28-15
Query, 38-4 CSS Customization, 28-17
Preferences, 1-2 new formats, 28-26
Product Structure Explorer query, 28-15
See PSE report format, 28-16
ProjectAuditEvent class, 29-4 stylesheets, 28-18
Promotion Request Approval Process, 25-13 XML Resource Bundles, 28-25
Promotion Request Review Process, 25-14 XML Result Format, 28-27
Promotion Request Workflow Processes XSLT Customization, 28-17
customizing, 25-13 customizing macros, 28-35
Properties, 1-2 ExportReport Template, 28-13
Properties and Preferences, 1-2 Generate Form URL, 28-33
Property files, 5-11 initial query steps, 28-2
db.properties file, 2-10 LoadReport Template, 28-11
debug.properties file, 2-10 macro generation form steps, 28-10
Editing, 2-11 macros, 28-9
service.properties file, 2-10 new client, 28-33
Index-5
parameters, 28-7 Event management, 36-4
QueryBuilder Types, 28-37 Managing, 36-2
Report Templates, 28-11 Overview, 31-1
URL customizing, 28-33 Query, 38-4
XSLT API, 28-32 Servlet Helper
XSLT standard, 28-26 GatewayServletHelper, 22-30
XSLT Stylesheets as Report Formats, 28-30 URLFactory Functionality, 22-30
Report Generation Form, 28-31 Sharing code, 2-8
Report Generation Output, 28-32 Simple business class, 37-2
Resource bundles site.xconf file, 5-11
Localizing, 40-5 siteMod directory, 5-3, 5-4
Location, 2-6 Soft Typing, 1-4
Revision control, 37-6 Source code management, 2-8
Revision controlled business class, 37-6 Source files, 2-3, 2-7
RevisionControlled Identity, 22-4 SQL path environment variable, 2-9
Rose model components, 2-7 SQL scripts, 2-3
RoseExtensions directory, 2-9 Location, 2-13
Runtime environment SQLPATH environment variable, 2-9
Files, 2-3, 2-5 src directory, 2-3
Runtime Resources Details, 2-7
building, 34-8 Stylesheets, 28-18
Supported API, 1-8
S class, 1-8
method, 1-9
Safe area, 5-2, 5-3 swmaint.xml script, 5-5
Search Synchronization robots, 25-6
Indexed-Search, 21-2 System, 22-2
Indexing Behavior, 21-6 System generation
IndexObject reference, 21-10 Overview, 32-1
IndexSearch, 21-6 Using, 32-50
Input Parameters, 21-2 System-Managed Identity, 22-15
overriding custom_getFieldData(), 21-9
SearchCondition, 38-5 T
selectable
EnumeratedType, 34-2 Template files, 5-12
SemanticKey, 22-11 Text tailoring, 5-2, 5-9, 5-10
Server logic tools.properties file
Overview of developing, 36-1 Use by code generator, 2-13
Server manager wt.classRegistry.search.path property, 2-13
Logging trace messages, 2-12 wt.classRegistry.search.pattern property, 2-13
service abstraction wt.generation.bin.dir property, 2-13
Design Pattern, 35-5 wt.generation.source.dir property, 2-13
Service Customizations, 1-5 wt.generation.sql.dir property, 2-13
Service provider property file, 5-27 wt.generation.sql.xxxTablesSize property, 2-13
service.properties file ToolsSetup.bat, 2-2
General description, 2-10 Trace logs
ServiceEvent abstraction Default location, 2-3
Design Pattern, 35-5 Trace messages
ServiceException abstraction Logging
Design Pattern, 35-6 From method server, 2-12
Services From server manager, 2-12
Access control, 31-5 Transactions, 38-8
Index-7
X
XCONF files, 5-11, 5-12, 5-28
xconfmanager, 6-2
XML Query results
top level elements, 28-29
XML Resource Bundles, 28-25
XML Result Format, 28-27
XSLT API
report generation, 28-32
XSLT Customization, 28-17
XSLT standard, 28-26
XSLT Stylesheets
Report Formats, 28-30
XSLT stylesheets
XML resource bundles, 28-25