WCAppDevGuide PDF
WCAppDevGuide PDF
WCAppDevGuide PDF
Windchill® 7.0
December 2003
Copyright © 2003 Parametric Technology Corporation. All Rights Reserved.
User and training documentation from Parametric Technology Corporation (PTC) is subject to the copyright
laws of the United States and other countries and is provided under a license agreement that restricts copying,
disclosure, and use of such documentation. PTC hereby grants to the licensed 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. 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.
Third-Party Trademarks
Adobe is a registered trademark of Adobe Systems. Advanced ClusterProven, ClusterProven, and the
ClusterProven design are trademarks or registered trademarks of International Business Machines Corporation in
the United States and other countries and are used under license. IBM Corporation does not warrant and is not
responsible for the operation of this software product. AIX is a registered trademark of IBM Corporation.
Allegro, Cadence, and Concept are registered trademarks of Cadence Design Systems, Inc. AutoCAD and
AutoDesk Inventor are registered trademarks of Autodesk, Inc. Baan is a registered trademark of Baan
Company. CADAM and CATIA are registered trademarks of Dassault Systemes. COACH is a trademark of
CADTRAIN, Inc. DOORS is a registered trademark of Telelogic AB. FLEXlm is a registered trademark of
GLOBEtrotter Software, Inc. Geomagic is a registered trademark of Raindrop Geomagic, Inc. EVERSYNC,
GROOVE, GROOVEFEST, GROOVE.NET, GROOVE NETWORKS, iGROOVE, PEERWARE, and the
interlocking circles logo are trademarks of Groove Networks, Inc. Helix is a trademark of Microcadam, Inc.
HOOPS is a trademark of Tech Soft America, Inc. HP-UX is a registered trademark and Tru64 is a trademark of
the Hewlett-Packard Company. I-DEAS, Metaphase, Parasolid, SHERPA, Solid Edge, and Unigraphics are
trademarks or registered trademarks of Electronic Data Systems Corporation (EDS). InstallShield is a registered
trademark and service mark of InstallShield Software Corporation in the United States and/or other countries.
Intel is a registered trademark of Intel Corporation. IRIX is a registered trademark of Silicon Graphics, Inc.
MatrixOne is a trademark of MatrixOne, Inc. Mentor Graphics and Board Station are registered trademarks and
3D Design, AMPLE, and Design Manager are trademarks of Mentor Graphics Corporation. MEDUSA and
STHENO are trademarks of CAD Schroer GmbH. Microsoft, Microsoft Project, Windows, the Windows logo,
Windows NT, Visual Basic, and the Visual Basic logo are registered trademarks of Microsoft Corporation in the
United States and/or other countries. Netscape and the Netscape N and Ship's Wheel logos are registered
trademarks of Netscape Communications Corporation in the U.S. and other countries. Oracle is a registered
trademark of Oracle Corporation. OrbixWeb is a registered trademark of IONA Technologies PLC. PDGS is a
registered trademark of Ford Motor Company. RAND is a trademark of RAND Worldwide. Rational Rose is a
registered trademark of Rational Software Corporation. RetrievalWare is a registered trademark of Convera
Corporation. RosettaNet is a trademark and Partner Interface Process and PIP are registered trademarks of
"RosettaNet," a nonprofit organization. SAP and R/3 are registered trademarks of SAP AG Germany.
SolidWorks is a registered trademark of SolidWorks Corporation. All SPARC trademarks are used under license
and are trademarks or registered trademarks of SPARC International, Inc. in the United States and in other
countries. Products bearing SPARC trademarks are based upon an architecture developed by Sun Microsystems,
Inc. Sun, Sun Microsystems, the Sun logo, Solaris, UltraSPARC, Java and all Java based marks, and "The
Network is the Computer" are trademarks or registered trademarks of Sun Microsystems, Inc. in the United
States and in other countries. VisTools is a trademark of Visual Kinematics, Inc. (VKI). VisualCafé is a
trademark of WebGain, Inc. WebEx is a trademark of WebEx Communications, Inc.
v
Command Beans ....................................................................................................................... 4-3
Command Delegates ................................................................................................................. 4-9
Attribute Handlers .................................................................................................................... 4-16
The Enterprise Layer .......................................................................................... 5-1
Enterprise Abstractions.............................................................................................................. 5-2
Simple Business Class........................................................................................................ 5-2
Folder Resident Business Class ......................................................................................... 5-4
Managed Business Class.................................................................................................... 5-5
Revision Controlled Business Class.................................................................................... 5-6
Iterated Folder Resident Business Class ............................................................................ 5-8
Cabinet Managed Business Cclass..................................................................................... 5-9
Document Abstractions............................................................................................................ 5-10
Part Abstractions...................................................................................................................... 5-13
Design Overview ............................................................................................................... 5-13
Change Abstractions................................................................................................................ 5-20
Change Item Classes ........................................................................................................ 5-22
Associations with Product Information .............................................................................. 5-25
Change Item Modeling Approach...................................................................................... 5-28
Change Items Classes ...................................................................................................... 5-29
Windchill Services .............................................................................................. 6-1
Windchill Packages.................................................................................................................... 6-2
access package — Access Control Service .............................................................................. 6-4
Design Overview ................................................................................................................. 6-4
External Interface ................................................................................................................ 6-6
Business Rules.................................................................................................................... 6-6
Event Processing ................................................................................................................ 6-7
admin package — Domain Administration Service .................................................................... 6-7
Design Overview ................................................................................................................. 6-7
External Interface ................................................................................................................ 6-8
Business Rules.................................................................................................................... 6-8
Event Processing ................................................................................................................ 6-8
content package — Content Handling Service .......................................................................... 6-8
Design Overview ................................................................................................................. 6-9
Working with ContentItems ............................................................................................... 6-12
Business Rules.................................................................................................................. 6-14
Event Processing .............................................................................................................. 6-14
content replication — Content Replication Service .................................................................. 6-14
fv.master — Master Service .............................................................................................. 6-14
fv.replica — Replica Service ............................................................................................. 6-14
Content vii
External Interface .............................................................................................................. 6-42
Business Rules.................................................................................................................. 6-42
Event Processing .............................................................................................................. 6-43
notify package — Notification Service ..................................................................................... 6-43
Design Overview ............................................................................................................... 6-43
External Interface .............................................................................................................. 6-45
Event Processing .............................................................................................................. 6-45
org package — Organization Service ...................................................................................... 6-46
ownership package — Ownership service ............................................................................... 6-47
Design Overview ............................................................................................................... 6-47
External Interface .............................................................................................................. 6-48
Business Rules.................................................................................................................. 6-48
Event Processing .............................................................................................................. 6-48
project package — Project Management Service ............................................................. 6-48
Design Overview ............................................................................................................... 6-49
External Interface .............................................................................................................. 6-50
Event Processing .............................................................................................................. 6-50
queue package — Background Queuing Service .................................................................... 6-50
External Interface .............................................................................................................. 6-52
Business Rules.................................................................................................................. 6-52
Event Processing .............................................................................................................. 6-52
router package — Routing Service .......................................................................................... 6-52
Design Overview ............................................................................................................... 6-53
Example ............................................................................................................................ 6-55
scheduler package — Scheduling Service .............................................................................. 6-56
External Interface .............................................................................................................. 6-57
Event Processing .............................................................................................................. 6-57
session package — Session Management Service ................................................................. 6-57
External Interface .............................................................................................................. 6-58
Business Rules.................................................................................................................. 6-58
Event Processing .............................................................................................................. 6-58
Standard Federation Service doAction() and sendFeedback() ................................................ 6-58
Design Overview ............................................................................................................... 6-59
External Interface .............................................................................................................. 6-60
Event Processing .............................................................................................................. 6-60
vc package — Version Control Service ................................................................................... 6-64
Design Overview ............................................................................................................... 6-65
External Interface .............................................................................................................. 6-69
Business Rules.................................................................................................................. 6-70
Content ix
SearchCondition................................................................................................................ 7-14
QueryResult ...................................................................................................................... 7-15
Multiple Class Queries ...................................................................................................... 7-15
Transaction .............................................................................................................................. 7-16
Paging ............................................................................................................................... 7-17
Developing Server Logic.................................................................................... 8-1
Service Management ................................................................................................................. 8-2
Automatic Service Startup................................................................................................... 8-2
Service Startup and Shutdown............................................................................................ 8-3
Service Event Management....................................................................................................... 8-3
Service Event Registration .................................................................................................. 8-3
Service Event Subscription ................................................................................................. 8-4
Service Event Notification ................................................................................................... 8-6
Service Event Exception Handling ...................................................................................... 8-6
Service Event Conventions ................................................................................................. 8-7
Implementing Business Data Types .......................................................................................... 8-7
Initializing Business Attributes............................................................................................. 8-7
Business Attribute Accessors.............................................................................................. 8-8
Overriding Accessor Methods ............................................................................................. 8-9
Validating Business Attributes............................................................................................. 8-9
Implementing the checkAttribute Method .......................................................................... 8-10
Business Attribute Aggregation ......................................................................................... 8-11
Business Attribute Persistence.......................................................................................... 8-11
Business Attribute Derivation ............................................................................................ 8-12
Implementing Business Services ...................................................................................... 8-12
Initializing Business Services ............................................................................................ 8-13
Business Service Operations ............................................................................................ 8-14
Vetoing Business Service Events...................................................................................... 8-15
Business Service Rules..................................................................................................... 8-15
Business Service Communication..................................................................................... 8-16
Lightweight Services ................................................................................................................ 8-16
The Modeling Implementation ........................................................................................... 8-17
The Inner Class Implementation ....................................................................................... 8-18
Updating a Master Through an Iteration .................................................................................. 8-22
Introduction........................................................................................................................ 8-22
Read-only and Queryable Master Attributes on the Iteration ............................................ 8-22
Updating Master Attributes via the Iteration ...................................................................... 8-23
Updating the Master and Iteration Separately................................................................... 8-23
System Generation ............................................................................................. 9-1
Content xi
Importing Windchill Beans to Visual Cafe ......................................................................... 10-6
Package Dependencies .................................................................................................... 10-7
WTContentHolder Bean .................................................................................................... 10-7
WTExplorer Bean ............................................................................................................ 10-11
PartAttributesPanel Bean ................................................................................................ 10-18
WTQuery Bean................................................................................................................ 10-21
WTChooser bean ............................................................................................................ 10-23
EnumeratedChoice Bean ................................................................................................ 10-24
Life Cycle Beans ............................................................................................................. 10-27
Spinner bean ................................................................................................................... 10-28
WTMultiList bean............................................................................................................. 10-28
AssociationsPanel bean .................................................................................................. 10-29
EffectivityPanel Bean ...................................................................................................... 10-33
FolderPanel Bean............................................................................................................ 10-35
AttributesForm Bean ....................................................................................................... 10-37
ViewChoice Bean ............................................................................................................ 10-43
PrincipalSelectionPanel Bean ......................................................................................... 10-46
PrincipalSelectionBrowser Bean ..................................................................................... 10-51
HTTPUploadDownload Panel Bean....................................................................................... 10-57
Overview ......................................................................................................................... 10-57
API................................................................................................................................... 10-58
Sample Ccode................................................................................................................. 10-59
Clipboard Support .................................................................................................................. 10-61
Copying a WTObject to the Windchill Clipboard ............................................................. 10-61
Retrieving a WTObject From the Windchill Clipboard ..................................................... 10-61
Accessing the System Clipboard..................................................................................... 10-62
Programming Outside the Sandbox Using security.jar .......................................................... 10-62
Threading............................................................................................................................... 10-64
Refreshing Client Data .................................................................................................... 10-66
Registering as a Listener for the Event ........................................................................... 10-66
Listening for the Event..................................................................................................... 10-67
Broadcasting the Event ................................................................................................... 10-67
Unregistering as a Listener to Events ............................................................................. 10-68
Online Help ............................................................................................................................ 10-68
Preferences............................................................................................................................ 10-71
The Preference Registry ................................................................................................. 10-72
Using Batch Containers ......................................................................................................... 10-73
Design Overview ............................................................................................................. 10-73
External Interface ............................................................................................................ 10-74
Content xiii
Evolvable Classes ............................................................................................. D-1
Background Information.............................................................................................................D-2
General Externalization Guidelines............................................................................................D-3
Hand-coded Externalization Guidelines .....................................................................................D-3
Migration Guidelines for Classes with Hand-coded Externalization...........................................D-4
Examples of Generated Externalization Code for Evolvable Classes .......................................D-4
Example of Generated Constants ....................................................................................... D-4
Example of a writeExternal Method..................................................................................... D-4
Example of a readVersion Method ...................................................................................... D-5
Example of a readOldVersion Method ................................................................................ D-6
GUI Design Process .......................................................................................... E-1
Overview of the Design Process ................................................................................................E-2
Gather User Requirements ........................................................................................................E-4
Define User Profiles ............................................................................................................ E-4
Define User Requirements .................................................................................................. E-5
Analyze Tasks............................................................................................................................E-6
Define Use Cases ............................................................................................................... E-7
Model Task Structure and Sequence .................................................................................. E-8
Develop Task Scenarios ................................................................................................... E-10
Develop Storyboards......................................................................................................... E-12
Design the GUI ........................................................................................................................E-13
Model Task Objects........................................................................................................... E-13
Design the GUI.................................................................................................................. E-14
Prototype the GUI.............................................................................................................. E-15
Evaluate the GUI ............................................................................................................... E-17
This table describes any major content changes or reorganizations since the last
release.
Table 1 Changes for Release 7.0
Change Description
Chapter 10, Developing Client Logic Removed the out of date Client Side
Access Control section. The available
APIs are documented via Javadoc for
the wt.access package
Chapter 12, Import Export Framework This is a new chapter since Release
6.2.
xv
xvi Windchill Application Developer’s Guide
About This Guide
Related Documentation
The following documentation may be helpful:
• The Windchill Customizer’s Guide
• The Windchill Installation and Configuration Guide
• The Windchill Client Technology 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 email if you
encounter problems using Windchill.
For complete details, refer to Contacting Technical Support in the PTC Customer
Service Guide enclosed with your shipment. This guide can also be found under
the Support Bulletins section of the PTC Web site at:
http://www.ptc.com/support/index.htm
The PTC Web site also provides a search facility that allows you to locate
Technical Support technical documentation of particular interest. To access this
page, use the following link:
http://www.ptc.com/support/support.htm
xvii
You must have a Service Contract Number (SCN) before you can receive
technical support. If you do not have an SCN, contact PTC License Management
using the instructions found in your PTC Customer Service Guide under
Contacting License Management.
Comments
PTC welcomes your suggestions and comments on its documentation—send
comments to the following address:
[email protected]
Please include the name of the application and its release number with your
comments. For online books, provide the book title.
Documentation Conventions
Windchill documentation uses the following conventions:
Topic Page
Directory Structure ..............................................................................................1-2
Artifact Management...........................................................................................1-6
Environment Variables........................................................................................1-7
Property Files ......................................................................................................1-8
1-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.
bin
Contains various batch scripts, such as ToolsSetup.bat.
cgi-bin
Contains the Windchill common gateway interface wrappers.
codebase
Contains the runtime environment files.
db
Contains the database properties file and SQL scripts.
docs
Contains PDF versions of the Windchill manuals.
lib
Contains the wtbeans.jar file, which holds the Java bean components that
have been developed for use with Windchill clients. For more information,
see Chapter 10, Developing Client Logic.
loadFiles
Contains files used to load initial data.
logs
Default location for trace logs when logging is turned on.
RoseAddIn
Contains the Windchill extensions to Rational Rose (customized menus,
property, and script files).
search
Contains Windchill extensions to Verity Search 97.
src
Contains development environment files.
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 % WT_HOME% \bin and JDK\bin. %
WT_HOME% 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 Javadoc wt.util package for further 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.
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
browser. It is used to build URLs for static resources such as images or
HTML files that reside under the server’s codebase directory.
• java.rmi.server.hostname, which specifies a host name used to identify the
server host. It is used by the Java RMI runtime for clients to look up the IP
address of the server. It can be specified as a symbolic name, such as a fully-
qualified Internet domain name, or numerically in dot notation (for example,
127.0.0.1). If not specified, the RMI runtime will use the name returned by
InetAddress.getLocalHost() method, which may return a name that is not
service.properties file
The service.properties file contains properties used by the Windchill service
delegate mechanism. This mechanism is a general facility for adding delegate
classes to an existing service to implement new, customized behavior. In this
context, service can mean any sort of Java mechanism that provides functionality
to other classes.
For example, assume a copy service exists that can make copies of certain classes
of objects. The service knows how to make copies only for objects of certain
classes: the classes for which copy service delegates have been created. Each
delegate implements an interface, defined as part of the copy service, that contains
the methods needed by the service. Once the delegate is created and put in the
codebase, the copy service is notified of its existence by adding an entry to the
service.properties file.
Generally, each service is accessed using a factory. The factory either returns
instances of delegates to perform services on particular classes of objects, or it
performs the operations on the objects itself by instantiating the necessary
delegates internally.
tools.properties file
The tools.properties file contains properties that are used by the System
Generation tools. The following properties within wt.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.
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. Examples or screen shots use Visual Cafe as an example of a supported
IDE, but 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 chapter 1, The Windchill
Development Environment) is set up correctly.
Topic Page
An Overview of the Windchill Development Process ........................................2-2
Verify The Development Environment...............................................................2-2
2-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, Eclipse or Visual Café (the IDE we have used),
is useful for building the client-side presentation portions of applications that
include HTML and Java applets. Examples or screen shots use Visual Cafe as an
example of a supported IDE, but 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.properties file entry named
– 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
Tip:
Create DatabaseTables
In Oracle SQL*Plus, create the tables by running the following command:
@helloWorld\make_helloWorld
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. You
can now execute the project in Visual Café using the Applet Viewer or run it
outside of Visual Café in a browser.
7. If you encounter an error that states the CreatePerson.class file cannot be
found, close Visual Café. Copy the contents of c:\ptc\windchill\codebase\
helloWorld to c:\ptc\windchill\src\helloWorld (these are the class files). Start
Visual Café and execute the applet. (Be sure the method server is running.)
Topic Page
Rational Rose and Windchill...............................................................................3-2
Windchill Modeling Heuristics ...........................................................................3-4
Windchill Foundation Abstractions.....................................................................3-8
3-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 chapter on server development) from which you can choose as much
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.
Topic Page
Command Beans................................................................................................. 4-3
Command Delegates............................................................................................4-9
Attribute Handlers .............................................................................................4-16
Customizing Command Delegates ....................................................................4-24
4-1
This chapter describes the classes and interfaces available in the following
packages, and guidelines on how to develop commands:
com.ptc.core.command
com.ptc.core.foundation
com.ptc.core.query.command
Note: The above packages do not contain all of the commands available in the
system. What they represent is a substantial core set of command beans, command
delegates and attribute handlers.
Design Overview
The simplest way to begin an overview of the design is to describe an example.
does this by illustrating a “Create Part” scenario. At the start of this scenario the
consumer makes a new CreatePersistentEntityCommand bean, sets various input
fields, most notably the source TypeInstance, filter1 and feedback specification,
and executes the command.
By design since the CreatePersistentEntityCommand is a kind of command that is
only executable in the server the corresponding command delegate is required to
run in the method server’s JVM. Thus, a special type of command delegate that
forwards to the server is made anew, the target delegate by name is set2, and the
forwarder is executed causing a remote method invocation to the method server
passing itself. Once in the method server the forwarder makes a new command
delegate given the name being the CreatePersistentEntityCommandDelegate and
executes it passing along the command bean.
The CreatePersistentEntityCommandDelegate performs any pre-processing logic
that is required. It then performs the execution logic which translates the given
source TypeInstance into a Persistable, stores the Persistable using the persistence
layer, and translates the returned Persistable from the persistence layer back into
the result TypeInstance. Now the CreatePersistentEntityCommandDelegate
performs any post-processing logic that is required3.
Once the CreatePersistentEntityCommandDelegate has finished with the post-
processing it returns as a result a TypeIsntance to the consumer. The consumer at
this point is then free to do whatever with the result.
Entity Commands
The AbstractEntityCommand class provides an abstract representation of a
command that can act upon an entity in the system. An entity is a business object
that is either transient or persistent. This abstract class specializes the notion of a
general command for an entity with the following key APIs.
1. source field: the input TypeInstance to be acted upon. Accessors are generated
for this private field.
2. result field: the output TypeInstance to be returned. The filter specifies what
attributes, constraints and descriptors to include in the TypeInstance for
return. Accessors are generated for this private field.
The AbstractPersistentEntityCommand class provides an abstract representation
of a command that can act upon a persistent entity in the system. This abstract
class specializes the notion of a general entity command by partitioning the
classification hierarchy such that below it is only commands designed to be used
for persistent entities (e.g., CRUD).
The AbstractIterationEntityCommand class further partitions the classification
hierarchy to define a set of commands that act upon persistent, iterated types of
entities in the system. This is where the notion of being able to do version control
and work-in-progress operations becomes realized. The
AbstractIterationEntityCommand specifies the following key APIs:
• targetId field: the iteration or version identifier that is the to be the next
identifier of the iterated/versioned entity upon completion of the command’s
execution. For example, the CheckinToVaultCommand can have this field
specified to be a different iteration identifier when the check in has completed
where say the checked out iteration identifier is 3, the checked in iteration
Repository Commands
The AbstractRepositoryCommand class provides an abstract representation of a
command that can act upon a repository in the system. A repository is the notion
of a container of objects that can be a database, flat file, file system, etc. This
abstract class specializes the notion of a general command for a repository. From
this abstract class it's expected that all repositories can be acted upon in both
common and specialized commands. For instance, a query could be thought of as
a general inquiry into a repository to "find" objects. The objects themselves could
live in a database or file system. It would be up to the specific command delegate
to realize the implementation. Additionally, as part of doing a general inquiry
there could exist the notion of server-side paging where only a single page, size
specified by the user, is returned to the client. Then the client could iterate through
pages as applicable, and ultimately close the paging session when done. This
abstract class provides the following key APIs:
• repositorySelector field: the repository to use to perform a repository
command against. Accessors are generated for this private field.
• resultContainer field: the container of type instances that are a result of a
command being executed against a repository. Accessors are generated for
this private field.
• resultSession field: the paging session, if one has been established. A paging
session represents the concept of iterating over a collection of items in a
repository. A paging session allows for fetching results from the
resultSession over multiple command executions. Accessors are generated for
this private field.
The AbstractIterationHistoryCommand class specializes the
AbstractRepositoryCommand to enable definition of specific commands that
collect historical iterated/versioned information, like an iteration or version
history. This abstract class provides the following key APIs:
• source field: the TypeInstance representing the point at which to start at in the
iterated/versioned history. Accessors are generated for this private field.
• The AbstractIterationHistoryDeletionCommand class specializes the
AbstractIterationHistoryCommand to define commands that perform
Modeling Guidelines
PTC development practices use Rational Rose to model and develop command
beans. Although this is the practice at PTC it is not required.
All types of command beans are modeled in Common subsystems such that their
deployment is accessible to both Client and Server subsystems. This is true for
server commands since they are currently remotely executable. PTC developed
command bean classes not have any compile or run-time dependencies on
Persistable classes.
Command Infrastructure Specification – Common Subsystem shows The
Command Infrastructure Specification - Common subsystem where many of the
command beans exist shown in the Command Bean Overview Class Diagram.
Other command beans more specific to Windchill services and enterprise objects
exist in similarly placed Common subsystems within the Windchill Foundation
Common and Enterprise Common subsystems.
Naming Guidelines
All command beans should be named in a manner to explicitly depict the
operation and on what they are designed for. That is to say the naming formula
verb + noun + “Command” should be applied. For example, if CRUD commands
didn’t already exist and were to be developed, they would apply only to persistent
entities and would be named as follows:
• CreatePersistentEntityCommand
• RetrievePersistentEntityCommand
• UpdatePersistentEntityCommand
• DeletePersistentEntityCommand
And this is exactly how these pre-existing CRUD commands are named.
Declaring command bean names in this manner makes it possible for consumers
to readily know what the command does and on what. Since there is no other API
on command beans that clarify their meaning, the name is required to do so.
Serialization Guidelines
All server types of command beans are modeled and generated as Serializable
types of classes. This is true since server commands are remotely executable.
Once server commands are no longer remotely executable they would no longer
be required to be Serializable. But since they are currently remotely executable
Implementation Guidelines
All local types of commands should extend from the AbstractLocalCommand
class. All server types of commands should extend from the
AbstractServerCommand class. This will enable inheritance of common
functionality that will ensure correct behavior. Implementing LocalCommand or
ServerCommand without extending the respective abstract class is not
recommended and is not part of PTC development practices.
Javadoc Guidelines
Command beans represent the set of APIs that are to be depended on and used by
consumers. What this means is that the command beans as a whole are the formal,
type-aware APIs of the system. Because of this all of the public and protected
command beans’ APIs should be clearly and thoroughly documented.
Command Delegates
Design Overview
Command delegates are the realization or implementation of command beans.
Command beans are the formal API and command delegates are the
implementation details. Command delegates are a customization point where one-
to-many command delegates can implement [most likely] one [and not very likely
many] command bean(s).
For example, the CreatePersistentEntityCommand bean has an OOTB default
command delegate being the CreatePersistentEntityCommandDelegate. In most
cases this command delegate will function as required. However, in the case of
some change objects they are required to be created in the repository related to
another applicable change object. Thus, based on the
CreatePersistentEntityCommand bean and type of change object a unique
command delegate can be looked up and executed as the correct implementation.
Command Delegate Overview Class Diagram shows the key part of the overall
command delegate classification hierarchy.
Note: Note: the initialize() and finalize() methods are overridable. But caution
must be used when doing so. Since these methods implement detailed
infrastructural logic for all commands it’s not recommended to override them.
Event Processing
As documented in the external interface of the
AbstractRemoteCommandDelegate class, it provides APIs to allow the
dispatching of any event defined by all Windchill services. Since this is only
possible for a subclass of the AbstractRemoteCommandDelegate, then these
events will only be dispatched within the server JVM.
For example, in the following code snippet the
RetrievePersistentEntityCommandDelegate dispatches either the
PREPARE_FOR_MODIFICATION or PREPARE_FOR_VIEW
PersistenceManager event depending on what the next operation is in the filter.
Modeling Guidelines
PTC development practices do not strictly establish whether or not command
delegates should be modeled using Rational Rose. Some command delegates have
been modeled while others have not.
Local types of command delegates are developed in Common subsystems such
that their deployment is accessible to both Client and Server subsystems. Server
types of command delegates are developed in Server subsystems to limit
deployment and accessibility for server-only dependencies.
The Command Infrastructure Implementation – Common and Server Subsystems
shows The Command Infrastructure Implementation - Common and Server
subsystems where many of the command delegates exist shown in The Command
Delegate Overview Class Diagram. Other command delegates more specific to
Windchill services and enterprise objects exist in similarly placed Common
subsystems within the Foundation Common and Enterprise Common subsystems.
Naming Guidelines
Command delegate naming conventions follow command bean naming
conventions with an added “Delegate” at the end of the class name. In most cases
where there’s a one-to-one mapping between bean and delegate the command
bean’s name + “Delegate” should be used to name the command delegate.
However, in cases of one-to-many, many-to-one or many-to-many command bean
to command delegate mappings it will be necessary to be either more of less
specific in the command delegate’s name. The following 2 examples illustrate the
many-to-one and one-to-many mappings:
1. For all query command beans there exists only one mapped command
delegate and thus should be name more general. It is named
QueryCommandDelegate where the following command beans are mapped to
it:
– AttributeContainerQueryCommand
– BasicQueryCommand
– FindPersistentEntityCommand
2. For the CreatePersistentEntityCommand it has a general purpose
CreatePersistentEntityCommandDelegate mapped to it. But also there exists
the following more specialized delegates for change objects:
– CreateWTAnalysisActivityCommandDelegate
– CreateWTChangeActivity2CommandDelegate
Serialization Guidelines
No command delegate should ever be Serializable. They are the implementation
details of commands where the command beans are sent across-the-wire, not the
command delegates.
Implementation Guidelines
In general, a command delegate’s implementation has the 3 main steps within the
doExecution() method, assuming that no customization has been done for pre-or-
post-processing:
1. Given the input TypeInstance populate a new Persistable. This by-in-large is
an act of in-memory translations.
2. Perform the server-side API invocation(s) against the Persistable via
Windchill services.
3. Populate the output TypeInstance with the acted upon Persistable. This has 3
minor steps where there’s an in-memory translation, derivation of server
calculated attributes and a query of all non-surface, missing attributes.
Additionally, the command delegate should be implemented where appropriate
levels of debugging and feedback messages are issued.
This type of implementation is known as a “wrapper” command delegate around
an existing Windchill service’s API matching the command. This isn’t always the
case. Command delegates can also execute other commands as well. This is the
case of the MacroCommandDelegate where it iterates through the sequence of
commands and executes each one in turn.
The UpdatePersistentEntityCommandDelegate Activity Diagram shows an
activity diagram for the UpdatePersistentEntityCommandDelegate. As can be
seen within the doExecution() activity the basic 3 step pattern was applied. The
only caveat is that constraints are refreshed and enforced as well. This pattern or
slight variation of it has been applied to all “wrapper” command delegates.
preprocess()
initialize()
doPreprocessing()
doExecution()
populatePersistable()
PersistenceHelper.manager.modify()
populateTypeInstance()
postprocess()
doPostprocessing()
finalize()
Attribute Handlers
Design Overview
Attribute Handlers are mechanisms for translating one of more attributes from a
Persistable to TypeInstance, or vice versa. They are translating in memory objects
only. Database hits should be avoided if at all possible. The order in which
attributes will be handled is not guaranteed or deterministic. Therefore, if
attributes require a certain order to their handling, a single Attribute Handler
should be written that handles both of them, at the same time, whenever any of the
related attributes are looked up. This handler then handles all of them
immediately, but in the proper order, then marks all of the involved attributes as
handled, so that they will not be handled multiple times.
Attribute Handlers generally do not validate arguments to make sure that business
rules are being followed. Generally, values passed to the get(...)and
set(...)methods are trusted, and if this results in an exception in a service, or a
ClassCastException, etc, then these exceptions will be passed through.
See StandardAttributeHandler for more information on when a specific
AttributeHandler must be written, and when the StandardAttributeHandler will
suffice.
Modeling Guidelines
PTC development practices do not strictly establish whether or not attribute
handlers should be modeled using Rational Rose. Only the
StandardAttributeHandler has been modeled while all others have not.
Since attribute handlers are purely implementation and no direct invocation is
made to them they should be packaged …server.impl packages.
Naming Guidelines
Attribute handlers should be named to show the attribute being handler +
“AttributeHandler.” Some examples of existing attribute handlers follow:
• ContentItemRoleAttributeHandler
• DataFormatReferenceAttributeHandler
• ContentItemCreatedByAttributeHandler
• PersistInfoCreateStampAttributeHandler
Serialization Guidelines
No attribute handler should ever be Serializable. They are the implementation
details of in-memory translations initiated by command delegates.
Implementation Guidelines
Attribute handlers can be implemented to handle one to many related attributes. In
the case of an attribute handler only handling one attribute the
CheckoutInfoStateAttributeHandler is shown to illustrate how it can be
implemented in the following code snippet:
public void get(
AttributeTypeIdentifier attr_type_id,
AbstractTranslatorCommand transl_cmd, AttributeStates
attr_states )
throws CommandException {
if (attr_states.findHandled(attr_type_id) != null)
return;
Workable work = (Workable) transl_cmd.getPersistable();
CheckoutInfo ci = work.getCheckoutInfo();
WorkInProgressState state = null;
if (ci != null)
state = ci.getState();
String value = null;
if (state != null)
value = state.toString();
putAttributeContent( attr_type_id, transl_cmd, attr_states,
value );
attr_states.makeHandled( attr_type_id );
}
For attribute handlers that are required to deal with multiple, related attributes at
the same time the VersionInfoAttributeHandler is shown to illustrate how it can
be implemnted in the following code snippet:
public void get(
AttributeTypeIdentifier attr_type_id,
AbstractTranslatorCommand transl_cmd, AttributeStates
attr_states )
throws CommandException {
AttributeTypeIdentifier versionIdATI =
getAttributeTypeIdentifier(
"versionInfo.identifier.versionId", transl_cmd );
AttributeTypeIdentifier versionLevelATI =
getAttributeTypeIdentifier(
"versionInfo.identifier.versionLevel", transl_cmd );
AttributeTypeIdentifier versionQualIdATI =
getAttributeTypeIdentifier(
"versionInfo.lineage.series.value", transl_cmd );
AttributeTypeIdentifier versionQualLevelATI =
getAttributeTypeIdentifier(
"versionInfo.lineage.series.level", transl_cmd );
AttributeTypeIdentifier[] ATIs = {
versionIdATI, versionLevelATI, versionQualIdATI,
versionQualLevelATI };
if (areHandled(ATIs, attr_states))
return;
Versioned version = (Versioned) transl_cmd.getPersistable();
try {
VersionInfo vInfo = version.getVersionInfo();
VersionIdentifier vIdentifier = null;
QualifiedIdentifier qIdentifier = null;
MultilevelSeries mSeries = null;
HarvardSeries hSeries = null;
Integer vLevel = null;
Integer qLevel = null;
String versionId = null;
Long versionLevel = null;
String qualifiedId = null;
Long qualifiedLevel = null;
if (vInfo != null) {
For attribute handlers that deal with some form of object reference
and server calculated attributes the ViewReferenceAttributeHandler
is shown to illustrate how it can be implemented in the following
code snippet:
(ObjectIdentifier)TypeIdentifierUtility.getObjectReference(
viewTii ).getKey() );
vm.setView( viewRef );
}
else if (viewName != null ) {
ViewReference viewRef = ViewReference.newViewReference(
(ObjectIdentifier)TypeIdentifierUtility.getObjectReference(
ServerCommandUtility.getViewTypeInstanceIdentifier(viewName)).getK
ey() );
vm.setView( viewRef );
}
else {
vm.setView( null );
}
}
catch (Exception e) {
throw new CommandException( e );
}
attr_states.makeHandled( ATIs );
}
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 .......................................................................................5-2
Document Abstractions .....................................................................................5-10
Part Abstractions ...............................................................................................5-13
Change Abstractions..........................................................................................5-20
5-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
The document classes are implemented based on the pattern established for
revision controlled objects in the wt.enterprise package. These classes,
WTDocumentMaster and WTDocument, provide concrete classes exhibiting the
management characteristics established in wt.enterprise and add specifics for
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
The source can be used to indicate how the part is procured, for example by being
made or bought. The type specifies how it can be decomposed, for example by
being separable (is assembled from components that can be taken apart to be
serviced), inseparable (is assembled, but can not be disassembled), or component
(is not assembled). The values of these properties can be altered by editing their
resource bundles.
Also, note that number and name are modeled as derived and are implemented to
set and get the real values from its WTPartMaster. The DerivedFrom property in
the Windchill tab of the attribute specification has been used to indicate that it has
been derived from the master’s attributes by specifying the database derivation;
also, the getters and setters have been overridden in a manner similar to the
following:
((WTPartMaster) getMaster()).get/set...(...)
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
Change Abstractions
The change2 package includes the basic service methods and change item classes
necessary to support change management. The change management module
provides the means by which users can identify, plan, and track changes to the
product information managed by the Windchill product data management system.
Note: The change2 package replaces the change package available in releases
prior to Release 4.0.
The following figure shows the five conceptual steps in the change management
process.
<<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
chapter 5, Windchill Services), 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 : IssuePriorit y = 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 it y()
<<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 isA ct 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 sisAct ivit 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
Windchill Packages .............................................................................................6-3
access package — Access Control Service .........................................................6-5
admin package — Domain Administration Service............................................6-9
content package — Content Handling Service..................................................6-11
content replication — Content Replication Service ..........................................6-17
effectivity package — Effectivity Service ........................................................6-19
federation package — Federation Service.........................................................6-24
folder package — Foldering Service.................................................................6-27
fv package — File Vault Service ......................................................................6-30
identity package — Identity Service .................................................................6-32
Import and Export Package ...............................................................................6-36
index package — Indexing Service...................................................................6-37
lifecycle package — Life Cycle Management Service .....................................6-40
locks package — Locking Service ....................................................................6-45
notify package — Notification Service .............................................................6-48
org package — Organization Service................................................................6-51
ownership package — Ownership service ........................................................6-52
project package — Project Management Service..............................................6-53
queue package — Background Queuing Service ..............................................6-55
router package — Routing Service ...................................................................6-57
scheduler package — Scheduling Service.........................................................6-61
session package — Session Management Service ............................................6-62
Standard Federation Service doAction() and sendFeedback() ..........................6-63
vc package — Version Control Service ............................................................6-69
vc package — Baseline Service ........................................................................6-75
vc package — Configuration Specification Service..........................................6-78
vc package — Version Structuring Service ......................................................6-85
vc package — Version Viewing Service...........................................................6-87
vc package — Work in Progress Service ..........................................................6-89
6-1
workflow package — Workflow Service ......................................................... 6-92
Engineering Factor Services ............................................................................. 6-98
EPMMemberLink ........................................................................................... 6-105
identity
Functionality to display the identity of business objects; that is, their type and
identifier (for example, a type of part and an identifier of part number).
vc
Version control; functionality to handle versions of objects. Version control
services described in this chapter include baselines, configuration
specifications, version structuring, version viewing, and work in progress.
Design Overview
An object is subject to access control if its type implements the AccessControlled
interface and implements either the DomainAdministered or the
AdHocControlled interface. The AccessControlled interface is simply a marker
interface, without any methods. Access control is enforced by access control lists
(ACLs), which associate principals to positive or negative sets of access
permissions. Permissions are defined by the AccessPermission class. When a user
attempts to perform an operation on an object, the ACLs are evaluated according
to the model set forth by the java.security.acl.Acl interface, and the access is
granted or denied.
Two types of ACLs can be associated to an object: a policy ACL, generated from
access control policy rules, and an ad hoc ACL, generated from ad hoc access
control rules. A single policy ACL applies to all objects of a specific type while
the ad hoc ACL is specific to a single object. The AccessPolicyRule class defines
policy rules and the AdHocControlled interface defines ad hoc rules. Both the
AccessPolicyRule class and the AdHocControlled interface implement the
AccessControlList interface, which associates a set of entries to a rule, and both
contain an entry set attribute (defined by the AclEntrySet class), which is a cache
of the entries. An access control rule entry is defined by the WTAclEntry class.
Ad Hoc ACLs
If an object is both DomainAdministered and AdHocControlled, then both the
policy and the ad hoc ACLs determine its access, in an additive manner. In the
same way as the policy ACL, the ad hoc ACL also contains a cached set of entries.
Although ACLs can map only principals to permissions, an ad hoc ACL
specification (represented by the AdHocAclSpec class) may also map roles to
permissions. Ad hoc access control rules can be generated from the ad hoc
specification by resolving the roles into principals. Depending on the role to
principal mapping used to resolve the roles, the same specification may generate
many different ad hoc ACLs.
External Interface
The functionality of this service is represented by the AccessControlManager
(accessible through the AccessControlHelper), and the AccessControlManagerSvr
(accessible through the AccessControlServerHelper).
StandardAccessControlManager defines the access control enforcement, access
control policy, and ad hoc access functionality. For enforcement, the most
important method is checkAccess, which takes a permission and either an object
or a domain and an object type as parameters and throws a
NotAuthorizedException if access is not granted to the current principal.
Business Rules
The rule for access control enforcement returns true (permission granted) if the
object is not access controlled, or if it is not ad hoc controlled and doesn't belong
to a domain. If the object belongs to a domain, the policy ACL is generated (or
retrieved if it already exists) and the ACL is evaluated. In case the object does not
belong to a domain or access is not granted by the ACL, the object is checked to
see if it is ad hoc controlled and has an ad hoc ACL. If it does, the ACL is
evaluated and access is granted accordingly. Otherwise, access is denied.
When applying access control enforcement to a DomainAdministered object, the
policy ACLs used are those associated with the domain to which the object
belongs and those associated with all ancestor domains. This allows objects to
have very different access control behavior even if they are of the same type.
External Interface
Access and manipulation of the domain of an object is accomplished by the
DomainAdministeredHelper, which both defines and implements the API. The
methods in this class are static. The methods for setting domains can be used only
with objects that have not yet been stored in the database (persisted). The
functionality defined in the AdministrativeDomainManager and
AdministrativeDomainManagerSvr can be accessed through the helper classes
AdministrativeDomainHelper and AdministrativeDomainServerHelper,
respectively. Changing the domain of a persistent object causes the posting of
PRE and POST events (see Event processing later in this section).
Business Rules
Four special domains are defined in the Site container during the installation
process: the Root, the System, the Default and the User domains. These
Event Processing
This service posts two events in case a change of domain is performed on a
domain administered object that is persistent. These events are:
PRE_CHANGE_DOMAIN and POST_CHANGE_DOMAIN. The administration
service listens for the following events:
PersistenceManagerEvent.PRE_DELETE - Listen to attempts to delete
AdministrativeDomain objects, to veto deleting the pre-defined and referenced
ones.
PersistenceManagerEvent.PRE_MODIFY - Listen to attempts to modify
AdministrativeDomain objects, to veto renaming the pre-defined ones.
PersistenceManagerEvent.INSERT - Listen to attempts to create
AdministrativeDomain objects, to veto attempts to create domains in the
Windchill PDM container with the same name and parent as one of the four pre-
defined domains in the Site container.
ContentHolders
DataFormat Class
Content Services
Querying
The method call to get the secondary content associated with a ContentHolder is
as follows:
This vector contains all the secondary ContentItems associated with the passed
ContentHolder.
The method call to get the primary content associated with a
FormatContentHolder is as follows:
ContentHolder holder;
holder = ContentHelper.service.getContents( holder );
ContentItem item = ContentHelper.getPrimary( holder );
Business Rules
The read and modification of content is based on the access rules of the
ContentHolder.
Event Processing
At this time, the ContentService does not broadcast any events.
External Interface
The Master service has no API for developers to use.
Event processing
At this time, the Master service does not emit any events for developers to use.
External Interface
The Replica service has no API for developers to use.
Event processing
At this time, the Replica service does not emit any events for developers to use.
External Interface
The InterSvrCom service has no API for developers to use.
Event processing
The InterSvrCom service does not emit any events for developers to use.
External Interface
The Shipping service has no API for developers to use.
Event processing
The Shipping service does not emit any events for developers to use.
External Interface
The Receiver service has no API for developers to use.
External Interface
The Generic Transport service has no API for developers to use.
Event processing
The Generic Transport service does not emit any events for developers to use
Design Overview
This section describes the effectivity interface, effectivity types, and configuration
item.
Effectivity Interface
Effectivity Types
Effectivity is an abstract class that supports the concept that a PDM object is
effective under certain conditions. Abstract subclasses of Effectivity include
DatedEffectivity and UnitEffectivity. Effectivity contains a reference to a
ConfigurationItem (configItemRef). This ConfigurationItem reference is
necessary for UnitEffectivity subclasses, and is optional for DatedEffectivity
subclasses.
Effectivity has two mechanisms for referencing its associated
EffectivityManageable object.
• versionedTarget is a reference to a versioned object and is used for classes
that implement EffectivityManageable.
• standardTargetReference is a reference to a non-versioned object and is used
for classes that implement EffectivityHolder.
The implementer simply calls EffectivityHelper.setEffectivityTarget, which
automatically initializes the proper reference.
ConfigurationItem
The following figure illustrates the ConfigurationItem.
ConfigurationItem
External Interface
The EffectivityHelper class provides methods for setting the configuration item
and target Effectivity Manageable object (WTPart) for an Effectivity object.
When creating WTLotEffectivity and WTSerialNumbered objects, both of these
methods should be called. When creating WTDatedEffectivity objects, setting a
Configuration Item is optional.
The EffectivityManager provides methods for retrieving Effectivity objects from
the database, for retrieving configuration item objects from the database, and for
storing, modifying, or deleting Effectivity objects. These methods are accessed
through EffectivityHelper.service.
Business Rules
The following business rules apply to effectivity:
• Any user who has access to modify a change order or change activity also has
permission to change the effectivity for all parts that are referenced by the
change order or change activity.
• The data model supports multiple effectivities per part version.
• Effectivity objects are never shared. Each part has unique effectivity
information.
• The user may not delete a configuration item if it is referenced by any
effectivity object.
• If the user deletes a part with effectivity, its effectivity information will be
deleted automatically from the database.
Event Processing
No events are posted by this service. This service listens for and acts upon the
following two standard Windchill events:
• When a POST_DELETE event for an EffectivityManageable object is
emitted, the EffectivityService will delete all of the Effectivity objects that
reference the deleted EffectivityManageable.
• When a PRE_DELETE event for a ConfigurationItem object is emitted, the
EffectivityService checks to make sure that no Effectivity objects reference
the ConfigurationItem. If any do, the EffectivityService will veto the delete,
and the ConfigurationItem may not be deleted.
Design Overview
The federation service is designed to be a plug and play component in the
Windchill system. The federation service is intended to be used for both client and
server development. Business objects, asserted as being federated in the object
model, are assigned a remote system information (serviceID) at creation and can
be promoted throughout the defined phases of an associated federation. The proxy
source information is held in the serviceID cookie, but instead operate on it
through the federation service’s external interface.
External Interface
The Federated interface provides an abstraction of a plug-and-play component.
The intent is that, in an object model, a business object would assert that is
Federated by implementing the Federated interface. With this assertion, the
business object can then be created as a proxy of remote object.
The FederationHelper provides an abstraction as the API to the
FederationService. The API’s method can be categorized as either local or remote
invocations. The local methods are getters of information, typically from cookies
that are held in the business object. The remote methods serve as wrappers to a
service that promotes server-side functionality.
Business Rules
As defined by the standard federation service access control rules, no constraints
are placed on the access of proxy objects.
Event Processing
The federation service is an event listener. The service listener listens for and acts
upon the following standard Windchill events.
When a PRE_STORE or a PRE_MODIFY event is emitted for a proxy object,
the federation service provides the opportunity to store or update associated
objects prior to storing or updating the proxy object itself by doing:
if ( obj instanceof Federated )
((Federated)obj).prepareForStore ();
Revising a proxy object is not allowed. Proxy objects are created against
source objects from remote system. The revision is prevented to ensure that
the proxy objects are consistent with the source objects.
When a POST_STORE or a POST_MODIFY event is emitted for a proxy
object, the federation service provides the opportunity to store or update
associated objects after storing or updating the proxy object itself by doing:
if ( obj instanceof Federated )
((Federated)obj).postStore ();
Folder Model
Typically, new objects that are to be foldered should extend the interfaces
provided in the wt.enterprise package. For simple foldered objects, use the
FolderResident class shown above. If additional characteristics (such as life cycle
management or versioning) are required, use the Managed or RevisionControlled
classes.
External Interface
The CabinetBased interface defines characteristics of information organized by
the foldering service. It has a name and a location that indicates the path to the
object in the cabinet and folder hierarchy.
The Foldered interface is asserted by objects that are to be organized into a folder.
An object can reside in (that is, be a member of) one and only one Folder.
The Folder interface is asserted for an object that organizes information. Both a
Cabinet and a SubFolder perform this organizing mechanism. There are two types
Business Rules
The business rules for foldering are based on the access control that it enforces.
The most basic rule is that to put an object into a folder, or remove it from the
folder, you must have modify permission on that folder. This is in addition to
whatever permission you must directly have to create or delete the object. To
move an object from one folder to another, you must have modify permission on
the source and destination folders, as well as permission to delete the object from
its source folder and to create it in its destination folder. An additional rule is that
you can not move an object from a shared cabinet to a personal cabinet.
The file folder is the equivalent of a directory on the disk drive. Folders are
logically grouped to form vaults. Each folder has a sequence number that defines
the order in which the folders within the vault will be used for storing content
items. When a folder overflows, the vault manager makes it read-only and begins
using the next available folder in the sequence. All the folders must be mounted to
all the method server hosts in order to provide access to content items stored in
them. Depending on the domain a content holder belongs to, a class and life cycle
state content item is stored in one of the vaults or in the ORACLE BLOB.
External Interface
There is no external API for customer use.
Event Processing
The service emits OVERFLOW events with the FvFolder object as a target on
folder overflow and the FvVault object as a target on vault overflow. An event is
emitted from within a transaction. Vetoing an event or throwing an exception has
no effect on the operation that caused the event to be emitted.
Object Model
The following figure shows the basic model to provide display identification
information about business objects. The following figure illustrates the basic
specification of identifiability and the identity factory mechanism.
Implementation
When implementing a delegate, the delegate must be a subclass of either the
DisplayIdentificationStandardDelegate or the
DisplayIdentificationVersionDelegate. The implementer must implement the
appropriate initialize methods as determined by the parent class. Typically, the
initialize() method itself is not overridden, but rather the initializeXXXX()
methods for the specific attributes of the identification object. Note that the
delegate objects should be written to be almost foolproof; that is, so that they can
always produce a DisplayIdentification object without throwing an exception.
From release 6.0, another option for subclassing delegates is the
DisplayIdentificationPersistableDeleagate. The initializeType() method in the
existing DisplayIdentificationPersistableDelegate has changed from initializing
the object using the introspection information, to dispatching the initialization
functionality to either "NonTypedDelegate" or "TypedDelegate" based on if the
object is "Typed" and let the proper delegate calculate the proper
"LocalizableMessage" for the object and set the object’s type to its correspondent
"LocalizableMessage". The subclass delegate should then implement the
initializeType() method by just calling its super’s initializeType() method to let
the DisplayIdentificationPersistableDelegate handle the work.
Design Overview
The design of the index policy manager follows the same pattern as the other
administrative policies (see Access control and Notification service, also in this
chapter). The Indexable interface marks those classes whose objects may be
indexed in external collections. Every Indexable object holds a list of the
collections (IndexerSet) in which it is currently indexed. Access to this list is
possible through the static methods of the IndexerHelper class.
Indexing Model
For each type and state, it is possible to define the collections the object should be
in. This definition is called an index policy rule and is represented by the
IndexPolicyRule class. Indexing policy rules are enforced by indexing policy lists
(IndexPolicyLists class). The lists are derived from all of the rules that apply to a
Collection Attributes
External Interface
The Index Policy Manager methods can be accessed through the
IndexPolicyHelper class.
Business Rules
Although the indexing mechanism can use any event posted by any service, the
implementation provided listens only to events that may cause the object’s index
entry to become out of sync with the object. This list of events ensures maximum
efficiency and ensures that index entries always remain up to date.
There is no need to create a rule that removes the object from the collections in the
event that the object is deleted. The Index Policy Manager creates an implicit rule
that does that.
Event Processing
/wt.admin.AdministrativeDomainManagerEvent/POST_CHANGE_DOMAI
N
/wt.vc.wip.WorkInProgressServiceEvent/POST_CHECKIN
/wt.fc.IdentityServiceEvent/POST_CHANGE_IDENTITY
/wt.fc.PersistenceManagerEvent/POST_DELETE
/wt.fc.PersistenceManagerEvent.POST_STORE
/wt.fc.PersistenceManagerEvent/POST_MODIFY
/wt.folder.FolderServiceEvent/POST_CHANGE_FOLDER
/wt.content.ContentServiceEvent.POST_UPLOAD
/wt.lifecycle.LifeCycleServiceEvent/STATE_CHANGE
/wt.vc.sessioniteration
.SessionIterationEvent/POST_COMMIT_SESSION_ITERATION
/wt.vc.VersionControlServiceEvent/NEW_ITERATION
/wt.vc.VersionControlServiceEvent/PRE_SUPERSEDE
External Interface
The LifeCycleManaged interface provides an abstraction of a plug-and-play
component. The intent is that, in an object model, a business object would assert
that it is LifeCycleManaged by inheriting (that is, it implements) the
LifeCycleManaged interface. With this assertion, the business object can be
transitioned to successive states as defined by a life cycle definition.
The LifeCycleHelper provides an abstraction as the API to the life cycle service.
The API’s methods can be categorized as either local or remote invocations. The
local methods are getters of information, typically from cookies that are held in
the business object. The remote methods serve as wrappers to a service that
promotes server-side functionality.
The LifeCycleServerHelper provides an abstraction of the server-side API to the
life cycle services. These methods can be invoked only from server-side
processing.
The LifeCycleService provides an abstraction that specifies and promotes server-
side functionality as a service that is remotely available for use by a client. This
interface is intended to define all the necessary server-side functionality for life
cycle management.
The LifeCycleServiceEvent provides an abstraction of a specialized keyed event
used by the life cycle service to signal other services that something has occurred.
This gives other services in a plug-and-play architecture the opportunity to act
accordingly upon these events. Validation, vetoing, and post-processing are
typical reactions to events.
The life cycle service emits the following events:
STATE_CHANGE
Emitted when an object’s state changes. This occurs at creation, promotion, or
demotion of an object.
ROLEHOLDER_CHANGE
Emitted when the role participants of a role are modified. This occurs when
the object is dropped or reassigned to a different life cycle.
ENABLE_LIFECYCLE
Emitted when a life cycle is enabled.
DISABLE_LIFECYCLE
Emitted when a life cycle is disabled.
Business Rules
Life cycle actions on life cycle managed objects are authorized by role
assignments. Roles are associated to principals in the definition of a life cycle
phase and a project, and are specific to a life cycle phase. Resolvable roles and
default assignments are identified in the definition of a life cycle phase. At
runtime, these roles are resolved to principals from a project specification, if the
corresponding roles are designated in the project.
There are four standard roles. The Submitter role players have authority to submit
the object for review. The Reviewer role players have authority to enter comments
and a signature designating approve or reject. The Promoter role players have
authority to promote, demote, deny, or drop the object. The Observer role players
have the right to view the object and view reviewer comments and signatures.
Additional roles can be added by updating the role resource bundle.
Design Overview
External Interface
The Lockable interface provides an abstraction of a plug and play component. The
intent is that, in an object model, a business object would assert that it is Lockable
by inheriting (that is, it implements) the Lockable interface. With this assertion,
the business object can then be locked and unlocked.
The LockHelper provides an abstraction as the API to the locking service. The
API’s methods can be categorized as either local or remote invocations. The local
methods are getters of information, typically from cookies that are held in the
business object. The remote methods serve as wrappers to a service that promotes
server-side functionality.
The LockService provides an abstraction that specifies and promotes server-side
functionality as a service that is available remotely for use by a client. The intent
is that this interface defines all the necessary server-side functionality for locking.
The LockServiceEvent provides an abstraction of a specialized keyed event used
by the locking service to signal other services that a locking activity is about to
begin or has occurred. This gives other services the opportunity in a plug and play
architecture to act accordingly on these events. Validation, vetoing, and post-
processing are typical reactions to events.
The LockException provides an abstraction of an abnormal occurrence or error in
the usage or processing of the locking service. This exception can be localized
through a given resource bundle, and other exceptions can be nested within it. The
most common occurrence of this exception is an attempt to lock or unlock a
business object that is already locked or unlocked.
Business Rules
As specified by the locking service’s standard access control rules, when an
attempt is made to lock an object, if it is not already locked and the given principal
has modify access to the object, then it is locked. If an attempt is made to unlock
an object that is already locked and the given principal has administrative access,
or the given principal is the one who originally placed the lock and has modify
access to the object, then it is unlocked. Otherwise, an exception is thrown
Event Processing
Event-based processing is performed on business objects asserted as being
lockable during [preparation for] database modifications and full restorations.
When a business object is [prepared for] being modified in the database, the
locking service listens to a dispatched event indicating that the modify is about to
begin and vetoes it if the business object is locked and the current session’s
principal is not the one who originally placed the lock. Otherwise, the
modification is allowed to take place. Therefore, it is valid to modify a business
object that is lockable if it is not locked. When a business object is being fully
restored from the database, the locking service listens to a dispatched event
indicating that the full restoration is beginning and restores the principal who
holds the lock in the business object’s lock cookie.
Design Overview
The Notification policy design follows the pattern for the administrative policy.
The Notifiable interface is created so that it can be implemented by the classes for
which notification should be sent. This interface contains no method. A notifiable
object may hold an event set that is specific to the object.
NotificationPolicy
Ad Hoc Notification
External Interface
The Notification Manager methods can be accessed through the
NotificationHelper class.
Business Rules
The users that are the final recipients of the messages must have an e-mail
attribute defined. Additionally, for messages generated by notification policies,
the user must have read access over the object to which the event occurred.
Although the notification policy mechanism can use any event posted by any
service, in practice the notification is limited to the events listed in the
wt.admin.adminEventResource class because these are used by the administrator
Event Processing
No event is generated. However, this service listens to the events specified in the
notification policy rules.
The list of events for the notification service includes the following in addition to
events defined in notify.properties:
/wt.admin.AdministrativeDomainManagerEvent/POST_CHANGE_DOMAIN
/wt.fc.PersistenceManagerEvent/POST_DELETE
/wt.fc.PersistenceManagerEvent/PRE_DELETE
/wt.vc.VersionControlServiceEvent/NEW_ITERATION
/wt.vc.sessioniteration.SessionIterationEvent/POST_COMMIT_SESSION_ITER
ATION
/wt.vc.wip.WorkInProgressServiceEvent/POST_CHECKIN
Org Package
The three main classes that compose this model are the WTPrincipal, and its
derived classes, WTGroup, and WTUser. WTPrincipal objects contain a name
which must be unique among users, groups, and administrative domains.
WTGroup can contain zero or more users. Also, a user can be in no group or in
many.
The WTUser class has fixed and queryable attributes, and name-value pair
attributes. Fixed attributes are the name (inherited from WTPrincipal),
authenticationName, and fullName. Besides these attributes, each WTUser has a
structured attribute holder for name-value pairs: the AttributeHolder (not shown
Design Overview
Ownership Model
Business Rules
Ownership is typically asserted on a business object prior to being stored in the
database. For example, in the Windchill implementation, this is done for foldered
objects as part of putting the objects into folders; the owner for the folder becomes
the owner for the object. Ownership may change as an object moves from one
folder to another.ge as an object moves from one folder to another.
Event Processing
Event-based processing is performed on Ownable objects as ownership changes
take place. An event is emitted just before the ownership change takes place,
inside the transaction that makes the change, and another event is emitted just
after the change has been made to the database. These events are
PRE_CHANGEOWNER and POST_CHANGEOWNER.
Project Model
Event Processing
The LifeCycleService is an event listener. The service listens for and acts on four
standard Windchill events.
• When a PRE_STORE event for a ProjectManaged object is emitted, the
LifeCycleService will initialize the state cookie by assigning an initial state to
the object.
• When a PRE_DELETE or PRE_CHANGE_IDENTITY event for a
ProjectManaged object is emitted, the service prevents the deletion or name
change.
• When a PRE_SUPERCEDE event for a ProjectManaged object is emitted, the
service manages the cookie information. The cookie information of the
superseded iteration is copied to the superseding object.
The project service emits a REPROJECT event when the project specified in a
ProjectManaged object is changed.
Queues are named and may contain many entries. Each entry may be in one of the
following states:
READY
Not yet executed.
EXECUTING
Executing.
COMPLETED
Executed successfully.
FAILED
Exception occurred during execution.
SUSPENDED
Operator suspended.
The main classes in this service and their relationships are shown in the figure
above. The ProcessingQueue class represents named queues created by the
applications or other services. Processing queues can be in one of two states:
active, in which requests are executed, and inactive, in which requests aren’t
executed (but new entries can be added). It supports methods to add and execute
External Interface
The external interface of the QueueService can be accessed through the
QueueHelper.manager object. It provides methods to retrieve queues and
associated information, set polling intervals, change queues from active to
inactive (start/stop), create and delete queues and entries, and even execute
specific queue entries.
Business Rules
The only two requirements for an arbitrary Java method to be able to be queued
are that it be public and static. Additionally, the programmer must provide a
principal (user or group) on behalf of whom the request will be executed. If the
method returns a value, the value is lost. Finally, the methods should preferably
not require operator intervention and certainly should not depend on end user
interaction.
Event Processing
No events are posted by this service.
Router Model
The routing service is a keyed event listener which listens for RoutingEvent
objects. The association between a routerEvent and the corresponding router
object determines how the event is handled. These elements are registered in the
wt.properties file.
A router object can operate in two modes: immediate and scheduled. Immediate
mode router objects, upon catching an event they are registered to handle,
immediately create and send an execution item to the queue. Scheduled mode
router objects, upon catching an event they are registered to handle, store the data
in a to-do list. The StandardSchedulingService invokes the static method
processToDoList defined in the scheduled mode router object. This method scans
the to-do list, creates execution items, and sends them to queues.
Example
This example shows how you can use this service by following these four steps:
1. Define an event:
Class SampleEvent extends wt.router.RoutingEvent
{
public SampleEvent(String evtType, Serializable eventTarget)
{
super(evtType, eventTarget);
}
}
4. Configure the router by placing the following five lines in the wt.properties
file:
Wt.router.1 = myRouter
myrouter.immediate=false
myRouter.NumberOfQueues=1
myRouter.method=SampleClass.aSampleMethod
myRouter.event.1=SampleEvent
Scheduler Model
The scheduling service manages the schedule items in the system. Schedule items
can be scheduled to run once or periodically, and can start immediately or be
deferred to start at a later time. Schedule items maintain a collection of their
histories and their method arguments. Method arguments can be any object. The
scheduler provides a higher-level interface to the wt.queue package. Schedule
items are executed with the same privileges as the user who created them.
The ScheduleHistory class provides the history of the execution instances. A
default CountedHistory object is supplied for use by agents that perform a number
of internal operations. The execScheduled method is provided so that when the
External Interface
There is no external API for customer use.
Event Processing
This service does not emit any events.
External Interface
The SessionManager contains methods for setting and getting the current
principal. The SessionManagerSvr contains methods for setting/resetting.
Business Rules
Although it is possible to retrieve the current principal from the client, the same
cannot be said about setting the current principal. This is only possible if the
current principal is itself a member of the Administrators group. Another way is to
set the wt.clientAuthenticatedLogin property (in the wt.properties file) to false.
This, however, should be done only for development, as it can be a serious
security breach.
Event Processing
No events are posted or listened to by this service.
External Interface
This is a supported API. The corresponding UI in Windchill is the Delegate
Administrator.
Event Processing
doAction executes one or more Info*Engine tasks selected by a specific logical
action name, and the types and physical locations of a specific set of objects
passed as parameters. sendFeedback sends feedback objects to clients.
doAction
public com.infoengine.object.factory.Group
doAction(String action,
Object[][] argv)
throws WTException
Example
import wt.federation.FederationHelper;
import wt.util.WTException;
import com.infoengine.object.factory.Att;
import com.infoengine.object.factory.Element;
import com.infoengine.object.factory.Group;
import com.ptc.core.util.feedback.common.FeedbackSpec;
import java.util.Enumeration;
group1.addElement( group1Elem1 );
group1.addElement( group1Elem2 );
...
try {
Object[][] argv = { {"testElement", testElement },
{"group1", group1},
{"elementArray", elementArray},
{"bool1", new Boolean(true)},
{"char1", new Character(a')},'
{"int1", new Integer(100)},
{"byte1", new Byte((byte) 9)},
{"double1", new Double(10000)},
{"short1", new Short((short) 99)},
{"float1", new Float(100.25)},
{"long1", new Long(4000)},
{"string1", "argv Test String"} };
if ( resultGroup != null ) {
System.out.println( "resultGroup:" );
showIeGroup( resultGroup );
}
else {
System.out.println( "resultGroup is null." );
}
}
if ( inElement != null ) {
System.out.println( "Element:" );
System.out.println( " Element Name: " +
inElement.getName() );
if ( inGroup != null ) {
Enumeration elements = null;
System.out.println( "Group:" );
sendFeedback
public void
sendFeedback(MethodFeedback feedbackObject)
throws FederationServicesException
Example
import wt.federation.FederationServerHelper;
import wt.federation.FederationServicesException;
import wt.feedback.StatusFeedback;
try {
// Send the client a StatusFeedback type feedback object.
// Federation Service sendFeedback() is accessed through
// FederationServerHelper.service
...
Versions
A business object’s iteration holds the object’s state and business qualifications.
These qualifications are used to form configuration specifications but in general
could be used as search criteria for ad hoc queries. Each iteration represents the
working history of a version. Incremental changes in the object, represented by
successive iterations, occur as the information is developed and changed. The
latest iteration (that is, the version) represents a development branch’s current
implementation; the previous iterations are all history. Iterations are identified by
unique values within a series. Additionally, unique fully-qualified identifiers can
also identify iterations. These fully-qualified identifiers show the history of a
particular iteration as it has been changed over time. In the reference
Note: Version control does not require Mastered objects to have any iterations,
but allows for many.
Note: Version control requires Iterated objects to have one and only one master.
This is a design constraint in that foreign key associations that can be auto
navigated (that is, the association between a master and its iterations) are required
to have one side being of cardinality equal to one (1).
Business Rules
As defined by the standard VC service’s access control rules, no constraints are
placed on the access of versioned objects. Furthermore, no constraints are placed
on the access of either mastered or iterated objects.
Event Processing
Event-based processing is performed on business objects asserted as being
Iterated during database storing, deletions, and full restorations.
When a business object is being stored in the database, the VC service listens to a
dispatched event indicating that the store is about to begin and stores the version’s
master, if needed.
After a successful store, the VC service listens to a dispatched event indicating
that the store has completed and signals all other interested services that a new
version exists if the stored iteration is either the first one created or is the first in a
new branch.
When a business object is being deleted from the database, the VC service listens
to a dispatched event indicating that the deletion is about to begin and vetoes the
deletion if the version is not the latest one in that branch of development.
Otherwise, it passes on vetoing the deletion.
After a successful deletion, the VC service listens to a dispatched event indicating
that the delete has completed and deletes all of the version’s iterations. If the
deleted version is the only one remaining related to a master, then it is deleted as
well.
When a business object is being fully restored from the database, the VC service
listens to a dispatched event indicating that the full restoration is beginning and
restores the iteration cookie’s creator/modifier, predecessor and master
references.
Design Overview
The baseline is a fundamental concept of configuration management. Because
PDM business objects are versionable and subject to change, numerous
External Interface
The Baselineable interface provides an abstraction of a plug-and-play component.
The intent is that, in an object model, a business object would assert that it is
Baselineable by inheriting (that is, it implements) the Baselineable interface. With
this assertion, the business object can then be part of a Baseline. The Baselineable
interface extends the Iterated interface and, therefore, must play the Iteration role
in the Master-Iteration (MI) pattern.
The Baseline interface is asserted for an object that can be associated with
Baselineable items. An out-of-the-box ManagedBaseline object implements the
Baseline interface and has name, number, and description attributes. It is also
Foldered and Life Cycle managed.
The Baseline service provides an abstraction that specifies and promotes server-
side functionality as a service that is available remotely for use by a client. The
intent is that this interface defines all the necessary server-side functionality for
baseline. The BaselineHelper provides an abstraction as the API to the Baseline
service.
The Baseline service provides basic APIs for adding and removing Baselineable
items. There are also operations for retrieving baseline information. A
convenience operation is also provided to automatically populate a Baseline by
navigating structured data. As the structure is navigated, each Baselineable item is
added to the Baseline. This navigation is customizable and an out-of-the-box
implementation is provided for navigating a part structure via the uses
relationship.
The BaselineServiceEvent provides an abstraction of a specialized keyed event
used by the Baseline service to signal other services that a baseline activity is
about to begin or has occurred. This gives other services the opportunity in a plug-
and-play architecture to act accordingly on these events. Validation, vetoing, and
post-processing are typical reactions to events.
Business Rules
The following business rules apply to baseline:
• Adding or removing items from a baseline is equivalent to modifying the
Baseline object and is subject to the access control properties of the baseline.
For example, if ManagedBaseline object is used, the life cycle state InWork
Event Processing
The Baseline service is both a producer and consumer of events. Whenever an
item is added, removed, or replaced in a baseline, events are generated prior to
and after the operation. For example, adding an item generates
PRE_ADD_BASELINE and POST_ADD_BASELINE events. Developers can
use the basic event listening mechanism to perform customized actions during
baseline operations. The Baseline service listens for the pre-modify, pre-delete,
and prepare for modify events to enforce business rules for items that are part of a
baseline.
Basic ConfigSpecs
wt.part PackageConfigSpecs
wt.part.WTPartStandardConfigSpec
This ConfigSpec is specifically written against parts (although it would work
for any ViewManageable, Workable, and LifeCycleManaged Iterated class).
WTPartConfigSpec
ProjectConfigSpec Example
//If the target class is Ownable, make sure it’s either owned by
// me or not owned at all (in a vault).
if (qs.getTargetClass() instanceof Ownable) {
qs.appendAnd();
qs.appendOpenParen();
qs.appendSearchCondition(OwnershipHelper.getSearchCondition(
qs.getTargetClass(), SessionHelper.manager.getPrincipal(),
true));
qs.appendOr();
qs.appendSearchCondition(OwnershipHelper.getSearchCondition(
qs.getTargetClass(), false));
qs.appendCloseParen();
}
The process API is simple, although it does require some implementation. The
target class might not have been Ownable and yet may have had Ownable
children, so ownership needs to be processed. Also, this ConfigSpec should return
a single version per master, so multiple versions will need to be processed down
to one. Fortunately, the LatestConfigSpec does all of these things, so this
implementation will simply return the result of executing its process API. The
code would look similar to the following:
public QueryResult process( QueryResult results )
throws WTException {
//##begin process% [ ]353B588501C5.body preserve=yes
//We can not simply return the results, children of the target
//class may have been Ownable, even though the target
//class was not.
//Let
//LatestConfigSpec handle this case because its process API
//accounts
//for that.
return (new LatestConfigSpec()).process(results);;
//##end process% [ ]353B588501C5.body
}
ConfigHelper
//Get the iterations for these masters. If masters are lost because
//no matching iterations were found, recover those masters for
//display.
QueryResult iterations =
ConfigHelper.recoverMissingMasters(usesMasters,
ConfigHelper.service.filteredIterationsOf(usesMasters,
someConfigSpec));
//If the user wants only the other side objects, return the
//iterations. Otherwise, pair up the links with the versions
//for those links.
if (onlyOtherSide)
return iterations;
else
return ConfigHelper.buildConfigResultFromLinks(uses,
IteratedUsageLink.USES_ROLE, iterations);
}
The references association couples data more loosely than the uses association.
For example, the referenced data may be important to a document, but the
document can be disseminated without it. For example, a design specification that
references the requirements specification it was written for is still complete on its
own. The struct package’s IteratedReferenceLink allows versioned data to
participate in references associations.
structPackage APIs
The struct package provides navigate APIs for both the IteratedUsageLink and
IteratedReferenceLink for convenience and because of minor behavioral nuances.
The navigateUses and navigateReferences APIs behave exactly as would
PersistenceManager’s navigate, however navigateUsedBy and
navigateReferencedBy return only versions; they filter out any iteration that is not
the latest iteration. The navigateUsesToIteration and
navigateReferencesToIteration APIs navigate the links to the masters, then
resolve the masters to their appropriate versions using the passed ConfigSpec. The
masters for which there are no appropriate versions are returned to indicate that
the association exists but has no qualifying representation given the ConfigSpec.
The return value for the navigate to iterations API, a QueryResult, consists of
those versions (and possibly masters) if onlyOtherSide is true. If it is false (that is,
the links are desired as well) a QueryResult containing Persistable’s as elements is
returned. Each element is an array of length 2 with the link in the 0th position and
the version (or master) in the 1st position.
External Interface
The Workable interface provides an abstraction of a plug and play component.
The intent is that, in an object model, a business object would assert that it is
Workable by inheriting (that is, to implement) the Workable interface. With this
assertion, the business object can then be checked out and checked in.
The WorkInProgressHelper provides an abstraction as the API to the WIP service.
The API’s methods can be categorized as either local or remote invocations. The
local methods are getters of information, typically from cookies that are held in
the business object. The remote methods serve as wrappers to a service that
promotes server-side functionality.
The WorkInProgressService provides an abstraction that specifies and promotes
server-side functionality as a service that is remotely available for use by a client.
The intent is that this interface defines all the necessary server-side functionality
for WIP.
The WorkInProgressServiceEvent provides an abstraction of a specialized keyed
event used by the WIP service to signal other services that a WIP activity is about
to begin or has occurred. This gives other services the opportunity in a plug-and-
play architecture to act accordingly on these events. Validation, vetoing, and post-
processing are typical reactions to events.
The WorkInProgressException provides an abstraction of an abnormal occurrence
or error in the usage or processing of the WIP service. This exception can be
localized through a given resource bundle and other exceptions can be nested
within it. The most common occurrences of this exception is when an attempt is
made to check in/out a business object but it already is checked in/out, and when
used incorrectly during a database modification, deletion, and navigation.
The WorkInProgressState provides an abstraction of the valid set of work-in-
progress states that a Workable object can exist within. The three supported states
are checked out, checked in, and working.
Business Rules
As defined by the standard WIP service’s access control rules, since a Workable
object is asserted as being Lockable, the service relies on the locking service for
applicable access control. Additionally, when an object is checked out, neither the
original checked out nor working copies can be checked out again.
Design Overview
The workflow package contains the following five subpackages:
engine
Directly responsible for the flow of control and data from an execution point
of view.
definer
Definition of workflow objects, that is, processes, activities, and the other
objects that compose the workflow network.
WorkflowEngine Package
External Interface
With the exception of wt.workflow.robots and wt.workflow.worklist, each
workflow subpackage has its own independent service.
The wt.workflow.engine.WfEngineHelper provides an abstraction of the API
required to instantiate and initiate workflow process instances. This service also
supports the invocation of robot activities through a specification of WfActivity.
The wt.workflow.definer.WfDefinerHelper provides an abstraction of the API
required to create and edit workflow definitions.
The wt.workflow.work.WorkflowHelper provides an abstraction of the API to the
workflow service to handle work item distribution, voting, and completion.
Business Rules
Work items are created by the workflow engine and are delivered to the user
through the work list interface and optionally via e-mail. An assigned activity may
have many assignees. Each assignee receives a work item in their work list. The
completion of an activity is based on the completion policy specified at define
time. For example, an assignment to a group may declare the policy as follows: all
members must act, a single member may act on behalf of the group, or a specific
number of group members must act. Depending on the completion policy, when
an assignee "accepts" or "completes" a work item, corresponding work items on
the work list of others are removed.
LifeCycle definition allows the integration of workflows into the specification for
each phase and gate. The life cycle service will transparently launch these
workflows when the life cycle managed object enters the phase or gate.
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
BuildSource
Allows the EPMDocument to be used by the Windchill build mechanism to
maintain a part structure
SupportingDataHolder
Allows the EPMDocument to have EPMSupportingData. An
EPMSupportingDataHolder can hold arbitrary Java objects, each tagged with
a name and an owner application name. This allows an application to store
application-specific data with the EPMDocument without having to extend
the Windchill schema.
EffectivityManageable
Allows the EPMDocument to be assigned an effectivity.
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/E 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.
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.
<<Interface>>
BuildRule
(from build)
Build Model
getApplicationTag()
initialize()
checkA ttributes()
getBuildSourc e()
setBuildSourc e()
getBuildTarget()
setBuildTarget()
EPMBuildLinksRule
EPMBuildLinksRule()
Build Rule
To create the rule, you must use the factory method defined on the class:
EPMBuildLinksRule rule = EPMBuildLinksRule.newEPMBuildLinksRule (
<document >, <part);
Once this has been done, you can use the Windchill build process to publish the
document structure to the part structure. This can be done in either of two ways:
• By building the EPMDocument:
BuildHelper.service.buildTarget (<document >,<config spec >);
• By building the WTPart:
BuildHelper.service.buildTargetsForSource (<part >,<config spec >);
If you are building a vaulted WTPart, the build process creates a new iteration of
the WTPart. If the WTPart is either checked out or in your personal folder, no new
iteration is created; instead, the usage links on the latest iteration are changed to
reflect the results of the build.
Topic Page
Persistence Manager............................................................................................7-2
Query .................................................................................................................7-12
Transaction ........................................................................................................7-16
Paging................................................................................................................7-17
7-1
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.
Operations that fetch objects from the database perform access control checks on
each object returned in the result set. These operations post POST_FIND or
POST_NAVIGATE events upon successful completion. 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 (see
wt.fc.PersistInfo). These operations also post a PRE_DELETE, PRE_MODIFY,
or PRE_STORE event before executing the database operation, and a
POST_DELETE, POST_MODIFY, or POST_STORE event after the operation
has completed successfully. Applications can listen for these events and perform
some related action in the same transaction.
wt.pom.Transaction controls transaction blocks. Transaction blocks are used to
group persistence operations so changes are committed only if all database
operations in the block were successful. Transaction.rollback() returns the data in
the database to the original state, but it is the application’s responsibility to refresh
objects in memory. This class should be used only by methods executing on the
server, not the client.
Details on the individual public operations are given in the following sections.
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 sections that follow
Persistence Manager
Also, note that setting the local variable to the return value is important in
programming the client because the underlying RMI makes copies of the objects
referenced by the arguments of the method. This means that objects passed as
arguments by the client in the create method are not changed by the operations
that occur on the method server.
Note: Setting the local variable to the return value is important in programming
the client because the underlying RMI makes copies of the objects referenced by
the arguments of the method. This means that objects passed as arguments by the
client in the modify method are not changed by the operations that occur on the
method server.
Save
The save method has the following declaration:
// Save the given object in the database
public Persistable save(Persistable wto)
throws WTException;
Note: Setting the local variable to the return value is important in programming
the client because the underlying RMI makes copies of the objects referenced by
the arguments of the method. This means that objects passed as arguments by the
client in the save method are not changed by the operations that occur on the
method server.
Delete
The delete method has the following declaration:
// Delete the given object from the database
public Persistable delete(Persistable wto)
throws WTException;
Refresh
The refresh method ensures that neither the client nor the server has a stale
business object. The refresh method has the following declaration:
// Refreshes the given object
public Persistable refresh(Persistable wto)
throws WTException;
Note: Setting the local variable to the return value is important in programming
the client because the underlying RMI makes copies of the objects referenced by
the arguments of the method. This means that objects passed as arguments by the
client in the refresh method are not changed by the operations that occur on the
method server.
Client code typically provides mechanisms that let you decide when business
information should be refreshed. Server code should refresh the business object
before performing any significant operation on that object. There is, however, one
Find
The find method has the following declaration:
// Queries for Persistable objects given a search criteria
public static QueryResult find(StatementSpec ss)
throws WTException;
// Retrieves any and all link objects that exist between two Persistable
// objects given their object identifiers. The method validates the
// resulting set of link objects retrieved from the database before
// returning them to the invoking method.
// Retrieves any and all link objects that exist between two given
// Persistable objects. The method validates the resulting set of
// link objects retrieved from the database before returning them
// to the invoking method.
In this example, the find method used an empty query specification, QuerySpec,
to retrieve all products. The target of the QuerySpec can be an abstract class,
allowing the query to span multiple subclasses. The find method returns its results
in a QueryResult object that acts like an enumeration.
Navigate
There are four navigate methods:
public QueryResult navigate(Persistable obj, String
role, Class linkClass) throws WTException
The first two methods have the same result as the last two with onlyOtherSide set
to True. When onlyOtherSide is true, the QueryResult contains the other side
objects rather than the links. When onlyOtherSide is false, the fully populated
links are returned.
The navigate method performs the following operations:
• Searches for objects of which the target object is a member, given the
specified role and QuerySpec.
lqs.appendWhere(new SearchCondition(
helpdesk.Product.class,
"name",
SearchCondition.EQUAL,
"AmazingApplets"), new int[] { 0 });
lqs.appendAnd();
lqs.appendWhere(new SearchCondition(
helpdesk.ProductRegistration.class,
"platform",
SearchCondition.EQUAL,
"NT"));
Get LOB
The getLob method has the following declaration:
public InputStream getLob( LobLocator lob )
throws WTException;
Given the lob locator, the getLob method returns the lob as an InputStream.
Given the name of the sequence as input, the getNextSequence method returns the
next value.
Example:
String sequenceNum =
PersistenceHelper.manager.getNextSequence("SOMENAME_seq");
Note: You must create the sequence before using this. For example:
wtpk.createSequence(’SOMENAME_seq’,1,1)
The method throws the NotAuthorizedException if the user is not allowed to view
the given object.
The prepareForView method performs the following operations:
• Retrieves a fresh copy of the object from the database.
• Checks the object for READ permission.
• Posts a PersistenceManagerEvent.PREPARE_FOR_VIEW event.
• Returns the object.
Search
The search method queries for a persistent object using the vector of
AttributeSearchSpecifications for the criterion. If any pre-query processing of the
data is required, it performs that processing.
The search method has the following declaration:
public QueryResult search( Class classname, Vector searchSpecVector )
throws WTException;
Query
The wt.query package contains the following classes for creating queries which
retrieve objects from the database.
When used with the find operation, QuerySpec can perform both single and
multiple class queries. The following sections discuss how to perform single class
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.
CompositeWhereExpression where =
new CompositeWhereExpression(LogicalOperator.AND);
where.append(new
SearchCondition(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NAME,SearchCondition.EQUAL,"XYZ"));
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.
SearchCondition has constructors for each of the java primitives and their
corresponding classes, plus Enumerated and AttributeRange. AttributeRange is
used as an argument to a SearchCondition constructor to create range conditions
in the WHERE clause (for example, myInt BETWEEN 1 AND 50).
SearchCondition also defines constants to use for the operation argument on the
constructors, such as EQUAL and GREATER_THAN.
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 QueryResult in this example will contain WTPartUsageLinks with both the
WTPartMaster and WTPart roles populated because onlyOtherSide is false. If
onlyOtherSide had been true, QueryResult would contain WTPartMaster objects.
// Join the WTPart class to the View class via the View
object ID and
wt.vc.views.ViewReference.KEY + "." +
wt.fc.ObjectIdentifier.ID,
wt.vc.views.View.class, WTAttributeNameIfc.ID_NAME);
while(result.hasMoreElements())
result.nextElement();
persistableArray[partIndex];
persistableArray[viewIndex];
Transaction
Transaction objects provide a mechanism that supports the standard concept of a
database transaction. It has the following methods:
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.
Paging
The basic idea behind paging is the concept of a "snapshot" query. When a paging
session is opened, a "snapshot" is taken of the results. These results can then be
fetched in pages over multiple calls. When all desired fetches are complete, the
paging session should be closed. This cleans up any data associated with the
paging session to free system resources. These system resources are significant so
a timeout property exists. If the timeout limit is reached, then the paging session is
automatically closed. Any further fetch requests would result in an exception.
Another configurable property is the paging limit (there is a system wide value
and this value can also be overridden when opening a paging session). Because of
the system resource required, a limit can be set such that if the result set size of the
"snapshot" query is less than this value, then all of the results are returned
immediately and no paging session is established. Note also that the results of the
initial "snapshot" query are access controlled. Only data that the user can access
(i.e. data that the user has read permission for) will be stored for subsequent page
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(
offset, range, pagingSessionId);
}
if(pagingSessionId <= 0)
{
// No paging session was established
break;
}
}
}
finally
{
if(pagingSessionId > 0)
{
PagingSessionHelper.closePagingSession(pagingSessionId);
}
Topic Page
Service Management ...........................................................................................8-2
Service Event Management.................................................................................8-3
Implementing Business Data Types ....................................................................8-7
Lightweight Services.........................................................................................8-17
Updating a Master Through an Iteration ...........................................................8-22
8-1
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 also Appendix B, Windchill
Design Patterns. This Appendix describes design patterns that represent
Windchill’s current best practices regarding development of server logic.
The Windchill Customizer’s Guide also includes descriptions of how to use and
customize Windchill services used in server development.
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.
Service Management
ManagerService is a manager which is used to startup and provide access to a pre-
defined list of managers. This list includes different managers for services
mentioned in Chapter 6, Windchill Services.
In addition to managing managers, the ManagerService provides a synchronous
event dispatch service. It could dispatch a vetoable or non-vetoable event to all
listeners for the event key. The listener may or may not object to the event. It
performs a synchronous "in thread/transaction" notification of each event listener
for the event branch identified by the event key. It calls the notifyEvent operation
on each subscriber
getManagerService().addEventListener(
new ServiceEventListenerAdapter(
this.getConceptualClassname() ) {
public void notifyVetoableEvent( Object event )
throws WTException
PersistenceManagerEvent pmEvent =
(PersistenceManagerEvent)event;
Persistable target = pmEvent.getTarget();
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
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;
}
Introduction
The master-iteration design pattern (described in Appendix B, Windchill Design
Patterns) 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, should a client need 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
on the master are number and name. In addition to being master attributes, they
are also identifying attributes. This means that they can be modified only by using
the IdentityService after the object has been persisted.
The Windchill reference implementation does not have an example of a master
class with non-identifying attributes. Currently, there is no support for
automatically persisting a master if its non-identifying attributes are updated using
derived attributes on the iteration. That is, the attribute could be modified by
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 .........................................................................9-2
How Rose UML Maps to Java Classes ...............................................................9-2
Implicit Persistable Associations Stored with Foreign ID References..............9-19
Extending the EnumeratedType class ...............................................................9-33
How Rose UML Maps to Info Objects .............................................................9-35
How Rose UML Maps to Database Schema .....................................................9-37
How Rose UML Maps to Localizable Resource Info Files ..............................9-40
Header ...............................................................................................................9-41
Resource Entry Format......................................................................................9-41
Using the Windchill System Generation Tool ..................................................9-43
Using Windchill System Generation in a Build Environment ..........................9-47
9-1
Overview of System Generation
The figure below shows the system generation process.
System Generation
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
Copyright Statement
Rose provides for a default copyright, and also for a copyright to be specified for a
particular package. This copyright statement is generated into the Java source
code for each 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;
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{
Class Body
Some constants are generated into the body of each class. The following are
examples of generated class constants:
// Constants used by the class
private static final String RESOURCE =
"example.exampleResource";
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
generated. If Default, they will be generated for classes that implement
ObjectMappable and for interfaces.
– ExplicitOrder (EnumeratedType set only) indicates whether the modeled
EnumeratedType options will be explicitly order in the resource info
(rbInfo) file. By default, a locale specific, alphabetical order will be
determined at run-time.
• Oracle Properties
Model of Operations
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
generated into concrete subclasses. See the Implementing Interfaces section for
details.
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.
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,
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.
Validation code will be generated if the attribute is modeled with a lower or upper
bound, as unchangeable, or as a required attribute. Each of these properties
appear, in Rose, on the Windchill tab for the attribute. Validation code will also be
generated if the attribute is modeled with a constrained type. That is, the attribute
is redefining an attribute, in the hierarchy, to be of a sub-type of the original
definition. If a validation method is generated, the setter code will invoke it. If
validation were generated for the "a1" attribute, the method would be
"validateA1".
If MyItem were an interface, only the accessor declarations and the label constant
would be generated into MyItem, because a Java interface can contain no
implementation. To the degree possible, the implementation aspects of interface
attributes will be generated into concrete subclasses. See the Implementing
Interfaces section for details.
• 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.
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 {
In this case, the code generator creates persistable Java classes that extend the
ObjectToObjectLink class and are capable of maintaining a persistent association.
Code-generated accessor methods return the role A and role B objects of the link.
This means that the developer need not be concerned with which object is the role
A object and which is the role B object.
Code-generated factory methods for Link classes take at least two arguments: the
role A object and the role B object. The factory methods are a result of the Link
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.)
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.
When a constructor is specified in a Rose model, two operations are generated in
the Java code: a public factory operation and a protected initialization operation.
The factory operation is called directly by the application to create a Java
instance. The factory method calls the initialize operation to put the instance into
an initial state.
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 );
}
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 a hook (readOldVersion) for reading in previous versions of the class,
which have been externalized. Code generation detects when the externalizable
signature of a class changes, and changes its internal version UID accordingly.
output.writeLong( EXTERNALIZATION_VERSION_UID );
super.writeExternal( output );
output.writeObject( a1 );
output.writeObject( a2 );
output.writeObject( a3 );
output.writeObject( list );
output.writeObject( (size == null - null :
size.getStringValue()) );
output.writeObject( timeline );
output.writeObject( work );
//##end writeExternal% [ ]writeExternal.body
}
if ( readSerialVersionUID == EXTERNALIZATION_VERSION_UID ) {
if ( !superDone )
super.readExternal( input );
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.EnumeratedType.toEnumeratedType(
size_string_value ); }
// in case old format
catch( wt.util.WTInvalidParameterException e ) {
size = MySize.toMySize( size_string_value );
}
timeline = (Timeline)input.readObject();
work = (MyAddress)input.readObject();
}
else
success = readOldVersion( input, readSerialVersionUID,
passThrough, superDone );
Extending EnumeratedTypes
Services contain the complete business logic and are expected to run only on the
method server, but forwarders go back and forth between the server and the client.
From the client, they invoke the business service methods running on the server.
At runtime, the forwarder binds to a service which is determined by the
registration of services that is done in the wt.properties file.
The forwarder classes are completely generated and provide no preserve markers
for developer editing.
Each persistable class maps to a database table. Each persistent attribute in the
class is mapped to a column name in the table. Structured attributes, like the
Address class shown earlier, are decomposed into their simple attributes.
Attributes are stored as lobs when no SQL-supported mapping is found, or if the
cardinality is greater than one (because SQL cannot allocate space for an
indefinite number of columns and rows).
Tables contain all the attributes they inherit from classes above them. Because a
class must be persistable to be in the database, all tables contain the persistInfo
attributes, including the object identifier.
The figure below shows a representation (not the actual columns) of the table that
is generated for the modeled class.
Header
Each resource info file contains the following lines that define certain file level
information.
ResourceInfo.class=wt.tools.resource.MetadataResourceInfo
ResourceInfo.customizable=true
ResourceInfo.deprecated=false
The first line, which executes the dropTable procedure of the WTPK package,
drops the MyItem table if it already exists. The next line is an informational
message that is displayed within SQL*Plus as the table is being created. Then the
table is created, with a primary key constraint on the object identifier. The storage
clause indicates that an initial extent of size 20K will be allocated by Oracle. This
corresponds to a SMALL size table. The last two lines insert a comment into
Oracle’s data dictionary to document when and why the table was created.
These comments can be viewed using SQL*Plus by entering the following
command:
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.
Topic Page
The Client Programming Model........................................................................10-2
Presentation Logic.............................................................................................10-3
Integrated Development Environments (IDEs).................................................10-3
Task Logic.........................................................................................................10-3
Windchill Java Beans ........................................................................................10-6
HTTPUploadDownload Panel Bean ...............................................................10-58
Clipboard Support ...........................................................................................10-62
Programming Outside the Sandbox Using security.jar ...................................10-63
Threading.........................................................................................................10-65
Threading.........................................................................................................10-65
Preferences ......................................................................................................10-72
Online Help .....................................................................................................10-69
Using Batch Containers...................................................................................10-74
The Rbinfo File Format...................................................................................10-86
10-1
The Client Programming Model
In the programming model we use, the client application is divided into two
components: the presentation logic for the client applet and the task logic for the
client model. The presentation logic implements the look and feel (that is, the user
interface) of the application. The task logic implements the client model and
interacts with the business logic of the application in the server.
Separating the presentation and the task logic provides several benefits:
• Independence
Changes made to one of the components need not have a corresponding effect
on the other component. If the logic needed to implement a task is changed,
changing the model has no effect on the presentation. For example, suppose a
change is made so the results of a database query are returned as an array of
objects rather than a QueryResult. Because this change is contained in the
implementation of the task logic, the presentation can be reused without
modification. Similarly, changes made to the user interface of a client
application do not affect the implementation of the task logic.
• Reuse
Multiple implementations of the presentation can be used with the same
implementation of the model. For example, suppose a developer wants to
create a user interface to support users with a keyboard but not a mouse. By
partitioning the client application, the developer need only create another user
interface to support keyboard input. The same model can be used for both
applications.
• Extensibility
The model can be extended to support evolving business logic.
Task Logic
The task logic implements the model. The model represents how the objects in the
application domain interact with each other to perform tasks, completely
independent of how the application looks or how the end user interacts with the
application. The objects and tasks are expected to have been identified as the
result of a design process (for example, the design process used to develop
Windchill applications is described in appendix E, GUI Design Process).
Implementing the task logic that has been defined involves three activities:
• Communicating with the method server and the database.
• Identifying and supporting the data to be cached on the client.
• Providing an API (that is, a set of methods) that can be used by the
presentation portion of the application to retrieve information.
i++;
} // End of ’while’ Loop
Client-Side Validation
The following example shows client-side validation. In this example, validation is
performed to ensure that the user has completed both the incident summary and
the incident detail. If the incident summary or incident detail is null or an empty
string, an InvalidAttributeException is thrown.
while( ( i < products.size() ) &&
( !found ) ) {
current_product = (Product) products.elementAt(i);
i++;
} // End of while'Loop'
if( !found ) {
Object params[] = { curCustomer.getCompanyName(),
product_name, product_version, product_release };
throw new WTException( null, RESOURCE, "productNotFound", params );
}
try {
inc_report=HelpdeskMgr.submitIncidentReport(inc_report,
curCustomer,
current_product );
incidentReports.addElement( inc_report );
track_number = inc_report.getTrackingNumber();
return track_number;
Package Dependencies
The Windchill beans are dependent on the following packages which must be
installed before using the beans:
• JDK 1.1.5 or higher
• symantec.itools.awt
• Windchill/codebase
WTContentHolder Bean
The WTContentHolder bean (wt.clients.contentholder.WTContentHolder)
provides support for manipulating the content of objects that implement the
wt.content.ContentHolder interface. WTContentHolder is useful for creating user
interfaces to create, view, and update such content-holding objects. This bean
provides support for the following manipulations on a ContentHolder object:
• Adding content files.
• Adding URLs.
• Removing content files.
• Removing URLs.
• Updating the attributes of a file.
• Replacing an existing content file with a new content file.
• Updating the properties of a URL.
• Viewing the properties of a file.
• Viewing the properties of a URL.
• Downloading the file contents.
• Opening a URL.
Property List
...
try {
myWTContentHolder.setContentHolder( report );
} catch (WTPropertyVetoException wtpve) {
wtpve.printStackTrace();
}
}
}
...
Notice that after invoking setReport, both the UpdateReportFrame and the
WTContentHolder used within this frame have a reference to the ContentHolder
object. The UpdateReportFrame has a reference in its local variable — report —
and the WTContentHolder bean has a reference which is set in the call to
setContentHolder(report). With both the frame and the bean having different
references to the same ContentHolder object, the programmer of the frame must
take care to ensure that both references remain current. For example, if a content
change is made using the WTContentHolder, and the ContentHolder is updated,
the copy of the ContentHolder maintained by the UpdateReportFrame has become
out of date.
The WTContentHolder bean provides an API that helps guard against references
to the same object getting out of sync. In addition to having an API that directly
manipulates a ContentHolder object, the WTContentHolder also has an API that
manipulates a ContentHolder via a wt.clients.util.ReferenceHolder. By
manipulating a ReferenceHolder, both the UpdateReportFrame and the contained
WTContentHolder manipulate the same ContentHolder object:
public class UpdateReportFrame extends java.awt.Frame {
...
try {
myWTContentHolder.setContentReference(
reportHandle );
} catch (WTPropertyVetoException wtpve) {
wtpve.printStackTrace();
}
}
}
...
Essentially, these are the only two actions needed to use the WTContentHolder
bean: adding the WTContentHolder to the parenting GUI screen, and initializing
the WTContentHolder with an appropriate ContentHolder object.
The WTContentHolder provides additional methods for enhancing the interaction
between the WTContentHolder and the container in which it exists. For example,
while the WTContentHolder bean provides a Save button which, when invoked,
causes all content changes to be saved, the WTContentHolder also provides a
method to programmatically save any content changes. Consider the Report
example. If the user clicks on the Cancel button in the UpdateReportFrame, and
changes to the content have been made that have not yet been saved, you may
want to prompt the user to save these changes:
public class UpdateReportFrame extends java.awt.Frame {
...
if( promptUserToSaveChanges() ) {
try {
myWTContentHolder.persistContentChanges();
} catch (PropertyVetoException pve) {
pve.printStackTrace();
setVisible( false );
}
...
WTExplorer Bean
The WTExplorer bean is an "Explorer" type browser for displaying items and
relationships.
The WTExplorer is a composite object which contains a tree view, a list view,
several status bars, and a splitter panel. Users can select nodes in the tree view and
display information about the node in the list view. Tree nodes can be expanded to
show structures.
Nodes can be created and added to the tree with objects which implement the
wt.clients.beans.explorer.Explorable interface. A sample adapter class,
wt.clients.beans.explorer.WTBusinessObject, is provided which implements the
Explorable interface and can be easily subclassed. The WTExplorer invokes the
getUses() method on the contained object to display its children in the tree view. It
invokes the getContents() method on the object to display its contents in the list
view.
API
The WTExplorer bean has a large number of attributes and methods. Methods are
provided to perform the following functions:
• Setting the foreground and background colors.
• Setting the preferred fonts.
• Adding, deleting, and refreshing nodes in the tree.
• Clearing the WTExplorer of all objects.
• Setting the column headings for the list view.
• Setting the methods to invoke on the contained objects.
• Setting the column alignments and sizes.
• Controlling caching of detail information for a node.
• Setting the text displayed in the status bars.
For more details on using WTExplorer, see the javadoc.
Sample Code
The following code sample shows an instance of the WTExplorer bean being
created and added to a component. The instance of the WTExplorer is initialized
with the specified font and color preferences, the desired column headings, the
methods to invoke on the contained objects, and the desired toolbar buttons.
GridBagLayout gridBagLayout;
gridBagLayout = new GridBagLayout();
setLayout(gridBagLayout);
setSize(730,423);
myExplorer = new wt.clients.beans.explorer.WTExplorer();
myExplorer.setTreeFont(new java.awt.Font("Dialog",
java.awt.Font.PLAIN,11));
try {
myExplorer.setListHeadingFont(new java.awt.Font("Dialog",
java.awt.Font.PLAIN,11));
}
catch(java.beans.PropertyVetoException e) { }
try {
java.lang.String[] tempString = new java.lang.String[8];
tempString[0] = new java.lang.String("Left");
myExplorer.setTools(tempString);
}
try {
myExplorer.setTreeStatusBarText("All Parts");
}
catch(java.beans.PropertyVetoException e) { }
try {
myExplorer.setListCellFont(new java.awt.Font("Dialog",
java.awt.Font.PLAIN,11));
}
catch(java.beans.PropertyVetoException e) { }
try {
myExplorer.setListFont(new java.awt.Font("Dialog",
java.awt.Font.PLAIN,11));
}
catch(java.beans.PropertyVetoException e) { }
myExplorer.setBounds(0,0,730,423);
myExplorer.setForeground(java.awt.Color.black);
myExplorer.setBackground(java.awt.Color.lightGray);;
// —- Callbacks
myExplorer.addListener(this);
// add as listener to refresh service
addRefreshListener();
/**
* Handle events from the WTExplorer.
*
* @param e the WTExplorerEvent
*/
/**
* Handle double-click events from the WTExplorer. The
* "view" task for the selectedobject will be launched.
*
* @param e the WTExplorerEvent
*/
/**
* Process the command from the WTExplorer. The WTExplorer
* will send commands when the user selects a toolbar
* button. The command will equals the name of the
* image on the toolbar button.
*
* @param e the WTExplorerEvent
*/
if ( e.getCommand().equals("update") )
{
processEditCommand();
}
else if ( e.getCommand().equals("view") )
{
processViewCommand();
}
}
/**
* Process the "Edit" command.
*
*/
/**
* Process the "View" command.
*
*/
if (selected_obj != null )
{
TaskDelegate delegate =
TaskDelegateFactory.instantiateTaskDelegate(
selected_obj );
if( delegate != null )
{
delegate.setParentApplet( getApplet() );
delegate.setParentFrame( getParentFrame() );
delegate.setObject( selected_obj );
delegate.launchViewTask();
}
else
{
System.out.println("Could not instantiate Task
Delegate for " + selected_obj);
/**
* Get the object currently selected in the explorer.
* If a list object is selected, use that object.
* Otherwise use the selected tree node.
*
* @return the selected object or null if no object is
* selected
*/
busobj = myExplorer.getSelectedDetail();
if (busobj == null)
{
node = myExplorer.getSelectedNode();
if ( node != null)
{
busobj = node.getObj();
}
}
if (busobj == null )
{
return null;
}
return busobj.getObject();
}
PartAttributesPanel Bean
Overview
PartAttributesPanel is a Java Bean component for manipulating
wt.clients.prodmgmt.PartItem objects. It is used in the Create, Update, and View
Part windows in the Product Information Manager client, and can be used by
developers who are customizing the Product Information Management
applications. The source code for the bean is contained in the
wt.clients.prodmgmt.PartAttributesPanel.java file.
The PartAttributesPanel bean contains properties to specify the class of the object
being manipulated and the attributes to be displayed. A label, maximum length,
and edit/view can be specified for each attribute.
The PartAttributesPanel bean dynamically constructs a user interface based on the
contained class and the specified information about the attributes. Boolean
attributes are represented as check boxes, enumerated types as choice lists, and
string and integer values are shown in text fields. The bean uses a grid-bag layout
to display the attributes in a tabular format. Labels will be displayed to the left of
each attribute. The layout has two attributes on each row. The labels have a grid
width of 1 and attribute elements normally have a grid width of 3 (TextAreas and
other large components will have a larger area). The attributes will be displayed in
the order they were specified in the attributes property for the bean.
After you modify values using the constructed user interface, the program can
invoke a method on the instance of the PartAttributesPanel bean to transfer the
modified values to the contained object.
API
The PartAttributesPanel bean contains methods to specify the following items:
• The class name of the object being manipulated.
• The attributes to display.
• The labels for each attribute.
• Whether an attribute is editable or view only.
• The maximum length for each attribute. (This property is currently used only
to determine if a string should be displayed in a TextArea instead of a
TextField element.)
• Where to position separators (horizontal lines) on the form.
• Where to position blank spaces on the form.
Form Designer
Sample Code
The following code demonstrates a possible use of this class:
Frame f = new Frame("AttributesPanel test");
PartAttributesPanel attributeBean = new PartAttributesPanel();
f.setSize(700,600);
f.setLayout(new BorderLayout());
try
{
// Set the class name of the object to be manipulated
attributeBean.setObjectClassName("wt.clients.prodmgmt.PartItem");
// Set the attributes to display in the panel
{
java.lang.String[] tempString = new java.lang.String[4];
tempString[0] = new java.lang.String("Number");
tempString[1] = new java.lang.String("Name");
tempString[2] = new java.lang.String("Source");
tempString[3] = new java.lang.String("Type");
attributeBean.setAttributes(tempString);
}
// Set the labels for the attributes
{
java.lang.String[] tempString = new java.lang.String[4];
tempString[0] = new java.lang.String("Number:");
tempString[1] = new java.lang.String("Name:");
tempString[2] = new java.lang.String("Source:");
tempString[3] = new java.lang.String("Type:");
WTQuery Bean
WTQuery provides a tool that allows you to include in your application the ability
to search for objects in the local Windchill database. WTQuery is comprised of an
optional title, a Tab panel containing an input area for search criteria, three
required buttons, three optional buttons, a check box indicating whether to append
to or replace the search results, and a list area for displaying search results.
The search results list area presents the results of the database query. The user can
clear this area by pressing the Clear button. A check box is available to the user
that determines whether to clear the list area between invocations of pressing the
Find button. By default, the list area allows multiple objects to be selected. To
restrict the list area to allow only single selection, use the setMultipleMode()
method. To obtain the list of selected objects, use either the getSelectedDetails()
or getSelectedDetail() method, depending on whether multiple or single selection
mode is in use.
The buttons are displayed in two columns. The required column contains the Find,
Stop, and Clear buttons. The optional column contains the OK, Close, and Help
buttons. By default, you get all six buttons. The functionality for the required
buttons and the Help button is handled by WTQuery (described later in this
section). The calling application can register a listener to be notified when the OK
or Close buttons are pressed. To register a listener, create a WTQueryListener
object and call the addListener() method using the WTQueryListener object as
input.
When creating a WTQuery object, you can specify a search filter string that is
passed to the method server when performing the database query. The search filter
is used to restrict the query. For more information about the possible values for
the search filter string, see the javadoc for wt.query.SearchTask.
This string designates wt.doc.WTDocument as the class that will be queried. The
tab panel will contain two tabs labeled Search Criteria and More Search Criteria.
The Search Criteria tab will contain an input field for name. The More Search
Criteria tab will contain an input field for description. The results list area will be
set up with columns for name, versionIdentity, and description.
The following example shows how to add WTQuery to a panel:
Panel queryPanel;
try {
WTQuery myQuery = new WTQuery("My Query Panel",
SearchTask.ALL_VERSIONS, false);
WTChooser bean
WTChooser is a subclass of WTQuery. WTChooser provides a tool that allows
you to include in your application the ability to search for objects in the local
Windchill database.
The WTChooser bean is not currently included in the wtbeans.jar file but the API
for incorporating WTChooser into an application is available.
WTChooser is comprised of an optional title, a tab panel containing an input area
for search criteria, six buttons, a check box indicating whether to append to or
replace the search results, and a list area for displaying search results.
The WTChooser object provides the ability to search for objects of a specified
class. The ChooserOptions class is distributed as source code and is used to
configure the attributes and classes available to WTChooser.
The ChooserOptions object consists of strings that associate a fully-qualified class
name with attributes to be used for restricting the query and attributes to be
displayed in the results list area. When calling WTChooser, you must specify a
fully-qualified class name that is defined appropriately in the ChooserOptions
object.
The format string is broken up into records. A one-character code followed by a
colon begins each record; a semi-colon and space combination are used as a
separator between records. The one-character codes are C, G, A and D:
C
Specifies a fully-qualified class name to query on. This must be the first
record in the format string.
G
Specifies text for the search criteria tabs. All attributes that follow will be
grouped on that tab until the next G record.
A
Specifies an attribute used in both the search criteria Tab panel and the results
list area. Attributes are displayed in the order they appear in the string.
D
Specifies an attribute used in only the results list area.
The search results list area presents the results of the database query. The user can
clear this area by pressing the Clear button. A check box is available to the user
that determines whether to clear the list area between invocations of pressing the
EnumeratedChoice Bean
Overview
The EnumeratedChoice bean is a simple extension of the java.awt.Choice class. It
allows you to specify a subclass of wt.fc.EnumeratedType. The display values of
the specified EnumeratedType subclass are used to populate the list of selectable
values.
API
The EnumeratedChoice bean contains methods to perform the following
operations:
• Specify the class name of the EnumeratedType object being manipulated.
• Set the selected EnumeratedType value in the list.
• Get the selected EnumeratedType value from the list.
• Allow the display of an empty (blank) choice.
Initially, only an empty Choice will be displayed in the Visual Cafe environment.
To populate the list of possible values, the bean must have valid values for the
following property:
EnumeratedTypeClassName
The fully qualified class name of the subclass of wt.fc.EnumeratedType (such
as, wt.part.Source).
Sample Code
The following code demonstrates a possible use of this class:
static public void main(String args[])
{
if (args.length == 0 )
{
System.out.println("supply enumeration class");
return;
}
String classname = args[0];
class DriverFrame extends java.awt.Frame
{
EnumeratedChoice choice = null;
public DriverFrame(String title)
{
super(title);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent event)
{
dispose(); // free the system resources
System.exit(0); // close the application
}
});
setLayout(new java.awt.BorderLayout());
setSize(300,300);
choice = new EnumeratedChoice();
add(choice, "Center");
myDialog.show();
.
. //create a LifeCycleManaged object
.
//myObject is the lifecycle managed object being created
myLifeCycleInfo.assign( myObject );
// Optionally at this point you could switch to view mode
myLifeCycleInfo.setMode( LifeCycleInfo.VIEW_MODE );
Spinner bean
The Spinner bean (wt.clients.prodmgmt.Spinner) is a subclass of the
symantec.itools.awt.util.spinner.Spinner class. It adds a new method,
addKeyListener(), to enable listeners to detect if users have modified the value in
the text field associated with the spinner. It also adds a new property,
CurrentDoubleValue, to allow the spinner to handle double values instead of
integer values.
For more information, see the javadoc in the symantec.itools.awt.util.spinner and
the wt.clients.prodmgmt packages.
WTMultiList bean
The WTMultiList bean (wt.clients.util.WTMultiList) is a subclass of the
symantec.itools.awt.MultiList class. It overrides several methods to improve the
display appearance of the bean on UNIX clients.
WTMultiList can also be configured to display attributes of modeled Windchill
business objects, such as Parts, Documents, and so on in a multicolumn list. When
taking advantage of this feature of WTMultiList, it is necessary to specify the
For more information, see the javadoc in the symantec.itools.awt and the
wt.clients.util packages.
AssociationsPanel bean
Overview
The AssociationsPanel bean (wt.clients.beans.AssociationsPanel) has a dev time
component and a runtime component. At dev time, you can drag this component
from the component library in Visual Café and drop it onto a container. The
properties can also be edited by using Visual Café’s Property Editor. At runtime,
this class retrieves the links of the object and displays them in a multilist.
The bean has an Edit and View mode. In edit mode, the user can add new
relationships, remove existing relationships, and update existing relationships by
editing the attributes on the link. In view mode, the user can view the relationships
and view the attributes on the link. The bean keeps track of the create, update, and
removes operations, and is able to persist the changes when save() is invoked.
API
The AssociationsPanel bean contains methods to specify the following items at
dev time:
• objectClassName - The class name of the object being manipulated.
• role - The string representing the Role to navigate.
• otherSideClassName - The class name of the OtherSideObject (a Persistable)
for viewing and displaying the attributes.
• otherSideAttributes - The attributes of the otherSideObject to be displayed in
the multilist.
• otherSideSchema - The developer can use a GUI at dev time to set the
otherSideClassName and the otherSideAttributes.
• labels - The labels for the columns of the multilist.
• multiListLinkAttributes - The attributes of the link to be displayed in the
multilist.
• linkClassName - The class name of the BinaryLink for creating new links.
• linkAttributes - The attributes of the link to be set in the AttributesForm bean
below the multilist.
• linkSchema - The developer can use a GUI at dev time to set the linkClass
name and the linkAttributes.
• mode - Edit or View. Edit will have Add and Remove buttons and the
attributes form is editable.
• chooserOptions - Must be a valid key in the
wt.clients.beans.query.ChooserOptions resource bundle. The string value
associated with the key sets the list of class names that the user can search for
upon pressing the Add button.
• relativeColumnWidths - Sets the relative widths of the columns in the
WTMultiList.
The AssociationsPanel bean contains the following methods to be used at runtime:
• setObject(Persistable myObect) - Sets the object to be manipulated.
• addHelpListener(helpListener) - Adds a listener to the bean’s help system.
{"CASCM", "C:wt.change2.WTChangeActivity2;
G:Search Criteria; " +
"A:number; A:name; A:lifeCycleState; A:projectId;
G:More Search Criteria; " +
"A:cabinet; A:modifyTimestamp; A:description"},
{"DocMasterSCM", "C:wt.doc.WTDocumentMaster;
G:Search Criteria; " +
"A:name; A:number;"},
{"CabSCM", "C:wt.folder.CabinetReference;
G:Search Criteria; A:name"},
{"PartMasterSCM", "C:wt.part.WTPartMaster;
G:Search Criteria; " +
"A:name; A:number"},
{"ConfigItemSCM", "C:wt.effectivity.ConfigurationItem;
G:Search Criteria; " +
"A:name; A:effectivityType; A:lifeCycleName;
A:lifeCycleState; G:More Search Criteria; " +
"A:lifeCycleAtGate; " +
"A:modifyTimestamp; A:createTimestamp; A:description"},
{CHANGEABLE_SEARCH_LIST, "wt.doc.WTDocument
wt.part.WTPart"},
{"BaselineSCM", "C:wt.vc.baseline.ManagedBaseline;
G:Search Criteria; " +
"A:number; A:name; A:lifeCycleState; A:projectId;
G:More Search Criteria; " +
"A:cabinet; A:modifyTimestamp; A:description"},
};
EffectivityPanel Bean
Overview
The EffectivityPanel bean (wt.clients.beans.EffectivityPanel) is used to create,
update, or view effectivity for an EffectivityManageable object. It has dev time
and runtime usage. At dev time, you can drag and drop the bean from the
Component Library in Visual Cafe onto a frame, applet, or panel. Properties, such
as background and mode, can be set at dev time. At run time, the user can view the
effectivity for the effectivity manageable object, or set/update the effectivity.
Overview
The FolderPanel bean provides support for objects that implement the
wt.folder.FolderEntry interface. This bean supports assigning the folder of a new
object, changing the folder of an existing object, and viewing the folder of an
existing object.
When not in view-only mode, the FolderPanel bean contains a label, a text field
for entering the location of a folder, and a "Browse..." button that launches the
WTFolderBrowserDialog to allow the user to browse for a folder.
When in view-only mode, the FolderPanel bean contains a label and text that
displays the location.
API
The FolderPanel bean has APIs that support the following actions:
• Setting the mode as view-only.
• Setting the list of cabinets from which the user can choose a folder.
• Restricting the list of cabinets from which the user can choose a folder to the
user’s personal cabinet.
• Restricting the list of cabinets and folders from which the user can choose to
those for which the user has a given permission.
• Assigning the folder of a foldered object.
• Changing the folder of a foldered object.
• Viewing the folder location of a foldered object.
For a complete list of the FolderPanel APIs, see the javadoc.
...
...
...
folderPanel1.setFolderedObject( new_doc );
new_doc = (WTDocument)folderPanel1.assignFolder();
return new_doc;
}
...
folderPanel1.addHelpListener( this );
}
AttributesForm Bean
Overview
The AttributesForm is a Java bean component for manipulating modeled
Windchill objects that implement the wt.fc.Persistable interface.
The AttributesForm bean contains properties to specify the class of the object
being manipulated and the attributes to be displayed. Alternatively, the schema
property of the bean can be set. The schema property specifies both the object
class name and the list of attributes to display for the class. Windchill
introspection mechanisms are then used to obtain information about each
attribute, including the display name, the maximum length, and whether the
attribute is required or updateable.
Setting the schema property in the Visual Café environment at design time
launches a custom property editor that allows browsing a list of all possible
Windchill modeled classes that implement the wt.fc.Persistable interface. The
developer can graphically select the class name and the attributes to display in the
form.
The AttributesForm dynamically constructs a user interface based on the
contained class and the specified information about the attributes. Boolean
attributes are represented as checkboxes; Enumerated types are represented as
choice lists; strings are shown in text fields or text areas; and integer and decimal
values are shown in Spinners. The bean uses a grid-bag layout to display the
attributes in a tabular format. Labels will be displayed to the left of each attribute.
The layout has two attributes on each row. The labels have a grid width of 1;
attribute elements normally have a grid width of 3 (TextAreas and other large
components will have a larger area). The attributes will be displayed in the order
they were specified in the attributes property for the bean.
API
The AttributesForm bean contains methods to specify the following items:
• The class name of the object being manipulated.
• The attributes to display.
• The labels for each attribute.
• Whether an attribute is editable or view only.
• Where to position separators (horizontal lines) on the form.
Package Dependencies
The bean is dependent on base classes from the Windchill packages. Ensure that
c:\ptc\Windchill\codebase is specified in the classpath for Visual Café.
Visual Manipulation
Many properties of the AttributesForm can be configured at development time.
See the following diagram for the Property List displayed in Visual Café for the
AttributesForm.
AttributesForm
Initially, only a blank panel will be displayed in the Visual Cafe environment. To
construct the user interface, the bean must have valid values for the following
properties:
• ObjectClassName - the fully qualified class name of the object (such as,
wt.part.WTPart)
• Attributes - an array of String values specifying the attributes to display (such
as, name, number, and so on).
Clicking on the schema property in Visual Café will launch a custom property
editor to allow the developer to visually select the class of the object and the
attributes of the class to display in the form:
Sample Code
The following code demonstrates a possible use of this class:
final Frame f = new Frame("AttributesPanel test");
AttributesForm attributeBean = new AttributesForm();
f.setSize(700,600);
f.setLayout(new BorderLayout());
f.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent event)
{
f.dispose(); // free the system resources
System.exit(0); // close the application
}
});
try
{
attributeBean.setObjectClassName("wt.part.WTPart");
{
java.lang.String[] tempString = new java.lang.String[5];
tempString[0] = new java.lang.String("number");
tempString[1] = new java.lang.String("name");
tempString[2] = new java.lang.String("view");
tempString[3] = new java.lang.String("partType");
tempString[4] = new java.lang.String("projectId");
attributeBean.setAttributes(tempString);
}
{
java.lang.String[] tempString = new java.lang.String[5];
tempString[0] = "true";
tempString[1] = "true";
tempString[2] = "true";
tempString[3] = "true";
tempString[4] = "true";
try
{
wt.part.WTPart part = wt.part.WTPart.newWTPart("airplane", "747");
part.setPartType(wt.part.PartType.toPartType("separable"));
wt.vc.views.View view = wt.vc.views.ViewHelper.service.getView(
"Engineering");
wt.vc.views.ViewHelper.assignToView(part, view);
attributeBean.setObject(part);
}
catch (wt.util.WTException wte)
{
wte.printStackTrace();
}
f.pack();
f.show();
ViewChoice Bean
Overview
The ViewChoice bean is a simple extension of the java.awt.Choice class. It allows
specifying an instance of wt.vc.views.View. The display values of the available
Views in the Windchill database are used to populate the list of selectable values.
API
The ViewChoice bean contains methods to perform the following operations:
• Set the selected View value in the list.
• Get the selected View value from the list.
• Allow the display of an empty (blank) choice.
For more details on using the ViewChoice bean, see the Javadoc for the
wt.clients.beans package.
Package Dependencies
The bean is dependent upon base classes from the Windchill packages. Ensure
that c:\ptc\Windchill\codebase is specified in the classpath for Visual Café.
ViewChoice
At design time, the Choice will show with a single possible value, "View" in the
Visual Cafe development environment. At runtime, the choice will be populate
Sample Code
The following code demonstrates a possible use of this class:
static public void main(String args[])
{
class DriverFrame extends java.awt.Frame
{
ViewChoice choice = null;
public DriverFrame(String title)
{
super(title);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent event)
{
dispose(); // free the system resources
System.exit(0); // close the application
}
});
setLayout(new java.awt.BorderLayout());
setSize(300,300);
choice = new ViewChoice();
choice.setBlankChoiceAllowed(true);
add(choice, "Center");
}
DriverFrame df;
df = new DriverFrame("ViewChoice Test");
df.show();
}
PrincipalSelectionPanel Bean
Overview
The PrincipalSelectionPanel bean allows the user to select a WTPrincipal
(WTUser or WTGroup) by either entering the name of a WTPrincipal directly or
by browsing lists of the available WTGroups or WTUsers. The bean can also
simply display a WTPrincipal. This bean contains a label, a text field, and a
browse button when used for selecting a principal. When the browse button is
clicked, a dialog box opens that allows the user to browse a list or lists for a
desired principal.
The bean has a selection mode (DISPLAY_SELECTION_MODE) and a view-
only mode (DISPLAY_VIEW_ONLY_MODE). In selection mode, the user is
allowed to select a WTPrincipal either by directly entering the name or by
browsing for it. The following figure shows the PrincipalSelectionPanel bean in
selection mode.
API
The PrincipalSelectionPanel bean contains methods to specify the following items
at dev time:
• displayMode - Allows the user to set the display mode for the panel
(DISPLAY_SELECTION_MODE or DISPLAY_VIEW_ONLY_MODE).
• labelMode - Allows the user to toggle between whether the principal label is
visible or not (LABEL_VISIBLE_MODE or LABEL_INVISIBLE_MODE).
• principalMode - Allows the user to set the principal selection mode for the
panel (PRINCIPAL_MODE, USER_MODE, or GROUP_MODE).
• browseButtonLabel - The label displayed for the browse button. A localized
label is supplied in the resource bundle; changing the browseButtonLabel in
the Property List will override the label from the resource bundle.
• principalLabel - The label displayed for the principal. A localized label is
supplied in the resource bundle; changing the principalLabel in the Property
List will override the label from the resource bundle.
The PrincipalSelectionPanel bean contains the following methods to be used at
runtime:
• getSelectedParticipant() - Returns the selected WTPrincipal object.
import wt.clients.beans.PrincipalSelectionPanel;
import wt.help.*;
import wt.org.WTPrincipal;
import symantec.itools.awt.StatusBar;
//{{INIT_MENUS
//}}
//{{REGISTER_LISTENERS
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
SymAction lSymAction = new SymAction();
testButton.addActionListener(lSymAction);
//}}
psp.setPrincipalMode(PrincipalSelectionPanel.PRINCIPAL_MODE);
psp.setDisplayMode(PrincipalSelectionPanel.DISPLAY_SELECTION_
MODE);
psp.setLabelMode(PrincipalSelectionPanel.LABEL_VISIBLE_MODE);
psp.setBrowseButtonLabel("Custom Browse...");
psp.setPrincipalLabel("Custom Principal:");
super.setVisible(b);
}
super.addNotify();
if (fComponentsAdjusted)
return;
//{{DECLARE_CONTROLS
wt.clients.beans.PrincipalSelectionPanel psp;
java.awt.Button testButton;
symantec.itools.awt.StatusBar statusBar;
//}}
//{{DECLARE_MENUS
//}}
catch (Exception e)
{
e.printStackTrace();
}
}
}
catch (Exception e) {}
}
}
PrincipalSelectionBrowser Bean
Overview
The PrincipalSelectionBrowser bean allows the user to select a WTPrincipal
(WTUser or WTGroup), an Actor, or a Role. This is done by selecting one of the
tabs on the left (Groups, Users, Actors, or Roles) and then selecting the desired
participants from the list displayed on the selected tab. This bean contains a tab
panel containing lists of the available participants, an Add button, an Add All
button, a Remove button, a Remove All button, and a list to display all the
selected participants.
The bean has a multiple selection flag. If the multiple selection flag is set to true,
the user can select multiple participants, and the buttons and selected participants
If the multiple selection flag is set to false, the user can select only a single
participant and only the tabs are displayed. The following figure shows the
PrincipalSelectionBrowser bean in single selection mode.
The bean allows each of the four tabs to be made invisible. For example, if you
want to allow the user to browse for only users, then the groups, actors, and roles
tabs could be made invisible and only the users tab would be displayed.
Sample Code
Following is a small example using the PrincipalSelectionBrowser bean:
//———————————————————————————————-
// java imports
//———————————————————————————————-
import java.awt.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.util.Vector;
//———————————————————————————————-
// wt imports
//———————————————————————————————-
import wt.clients.beans.PrincipalSelectionBrowser;
import wt.help.*;
import symantec.itools.awt.StatusBar;
psb.setMultipleSelection(true);
psb.setGroupSelectionTabVisible(true);
psb.setUserSelectionTabVisible(true);
psb.setActorSelectionTabVisible(true);
psb.setRoleSelectionTabVisible(true);
//{{INIT_MENUS
//}}
//{{REGISTER_LISTENERS
SymWindow aSymWindow = new SymWindow();
this.addWindowListener(aSymWindow);
SymAction lSymAction = new SymAction();
TestButton.addActionListener(lSymAction);
//}}
}
public PSBTestFrame(String title)
{
this();
setTitle(title);
}
public void setVisible(boolean b)
{
if(b)
{
setLocation(50, 50);
}
super.setVisible(b);
}
super.addNotify();
//{{DECLARE_CONTROLS
wt.clients.beans.PrincipalSelectionBrowser psb;
java.awt.Button TestButton;
symantec.itools.awt.StatusBar statusBar;
//}}
//{{DECLARE_MENUS
//}}
catch (Exception e)
{
catch (Exception e) {}
}
}
void TestButton_ActionPerformed(java.awt.event.ActionEvent
event)
{
Vector v = new Vector();
v = psb.getSelectedParticipants();
System.out.println(v);
}
}
Overview
The HTTPUploadDownloadPanel bean is used to specify the primary content of a
FormatContentHolder object, such as a WTDocument. It allows the user to select
whether the primary content is a file or a URL, enter the file path or URL, and
remove an existing primary content entry. When the save() method is called, the
primary content’s file path or URL will be persisted, and if the primary content is
a file then that file will be uploaded. If the file already uploaded is identical to the
file in the local file path, a message will be displayed telling the user that the file
wasn’t uploaded because it hadn’t changed.
When Primary File is selected in the drop down menu, the user can hit the Browse
button to launch a FileLocator dialog to browse for the file path.
Primary File
Primary URL
To remove a primary content item, the user can either click the Remove Primary
button or delete the contents of the text field. The Remove Primary button will
become disabled and the text field will display a localized message of "No
Primary".
No Primary
For situations where only files are valid as primary content, the
ChooseFileOrURL dropdown can be hidden.
There is also a Get button which is typically hidden when this bean is used in the
Windchill client. If displayed, the Get button is disabled when Primary File is
selected and enabled when Primary URL is selected. Clicking the Get button will
launch a browser window displaying the URL.
API
The HTTPUploadDownloadPanel bean contains methods to get/set the following
items:
• The FormatContentHolder object being manipulated
(get/setDocumentHandle).
• The target type (File or URL), target path, default filename (used by
FileLocator), mode, and hostURL values (get/setTarget, get/setTargetType,
get/setDefaultFilename, get/setMode, get/setHostURL).
• Whether or not the applet containing the bean is embedded in an HTML page
which controls the applet via Javascript (is/setEmbeddedApplet).
• Whether or not the Get button, ChooseFileOrURL menu, and/or Remove
Primary button are visible (is/setGetButtonVisible,
setChooseFileOrURLVisible, is/setRemovable).
Once the bean is displayed, there are also methods available to:
• See whether the file path entered is valid on the local system (isValidTarget).
• Determine whether the file on the local system is identical to the file in the
database (checksumsMatch).
Sample Ccode
See wt.clients.doc.CreateDocumentFrame for use of this class in the Java client.
The following code demonstrates a possible use of this class within an applet
embedded in an HTML page. Initializing the HTTPUploadDownloadPanel:
/**
* Upload mode indicator
*/
public static final int UPLOAD = HTTPUploadDownloadPanel.UPLOAD;
/**
* Download mode indicator.
*/
public static final int DOWNLOAD = HTTPUploadDownloadPanel.DOWNLOAD;
hTTPUploadDownloadPanel1 =
new wt.clients.util.http.HTTPUploadDownloadPanel();
hTTPUploadDownloadPanel1.setLayout(null);
hTTPUploadDownloadPanel1.setBounds(0,0,998,452);
hTTPUploadDownloadPanel1.setFont(new Font("Dialog", Font.PLAIN, 11));
// hide getButton
hTTPUploadDownloadPanel1.setGetButtonVisible(false);
add(hTTPUploadDownloadPanel1);
//}}
hTTPUploadDownloadPanel1.setRemovable
( getParameter( "removable", "false" ).equalsIgnoreCase("true"));
hTTPUploadDownloadPanel1.setHostURL ( getParameter( "hosturl", "" ));
hTTPUploadDownloadPanel1.setTargetType( getParameter( "type", "FILE" ));
hTTPUploadDownloadPanel1.setDefaultFilename
( getParameter( "defaultfile", "*.*" ) );
try {
if ( ( hTTPUploadDownloadPanel1 != null ) &&
( hTTPUploadDownloadPanel1.isDirty() ) ) {
if (!hTTPUploadDownloadPanel1.save()) {
Object[] params ={getDocumentIdentity(getDocument()
,getContext().getLocale())};
error_msg = WTMessage.getLocalizedMessage( RESOURCES,
DocRB.CONTENT_NOT_UPLOADED,
params,getContext().getLocale());
}
}
... other applet logic dealing with the status of the save ...
} catch ( WTException e ) {
String identity = "";
LocalizableMessage message_id = getDocument().getDisplayIdentity();
return error_msg;
} // end saveContents()
Because any applet code could potentially use this package to gain access to
privileged operations, another layer of security is maintained by the security
package. This allows the user to grant or deny usage of security.jar by codebase
(see the following figure). For example, code from www.widgets.com/windchill
may be granted by the user; an new applet from www.rogueapplets.com would
prompt the user to either grant or deny privileges to the given operation.
To load the security package, the applet tag must specify the location of the signed
code. Netscape loads signed classes specified in the ARCHIVE tag while Internet
Explorer loads signed classes specified by the CABINETS parameter. The
following tag will load the security package for either browser:
<applet code="mypkg/myapplet.class"
codebase="/windchill" archive="wt/security/security.jar">
The following tag can also be used with the bootstrap loader:
<applet code="wt/boot/BootstrapApplet.class"
codebase="/windchill" archive="wt/security/security.jar">
<param name="cabinets" value="wt/security/security.cab">
<param name="boot_jar" value="wt.jar">
<param name="boot_class" value="mypkg.myapplet">
</applet>
When the security package has been loaded, the applet may use the Access classes
to perform operations outside the sandbox. Currently, the security.jar package
provides FileAccess, NetAccess, PropAccess and RuntimeAccess. The basic
template for using these operations is as follows:
File input = new File(FILENAME);
FileAccess fa = FileAccess.getFileAccess();
FileInputStream fis = fa.getFileInputStream(input);
. . .
fa.delete(input);
Threading
The following example shows a way to create a frame and populate lists within it.
This example uses threading to process database events in parallel rather than
sequentially and, thus, populates the frame more quickly. Three threads are
started: one to get user attributes, one to get group membership, and one to get all
available groups. When all three threads complete, the frame is activated.
private static final int ALL_GROUPS = 3;
private static final int MY_GROUPS = 2;
private static final int ATTRIBUTES = 1;
ActionThread(int action) {
this.action = action;
}
/** ...threadStatus
* threadStatus is used for tracking when all the threads
* used to create & populate the user frame have completed.
* When each thread is run, it calls threadStatus to report
* its completion status and any error message it captured.
* When all the threads have completed, if no errors occurred
* the frame is activated. If something failed a msgbox shows
* the captured err message, then the frame is destroyed.
**/
if (!my_status)
//Save any error information
thread_msg = thread_msg + ErrMsg + " ";
if (threads_complete == threads_needed) {
this.setCursor(Cursor.getDefaultCursor());
if (thread_status) {
//activate
this.setEnabled(true);
}
else {
//all threads are complete but someone failed
DiaMessage m = new DiaMessage(this,
this.getTitle(),true);
thread_msg = "Action failed. The following error
occurred: " + thread_msg;
m.show(thread_msg);
this.dispose();
}
} //end if (threads_complete)
}
//deactivate stuff
this.setEnabled(false);
threads_needed = 3;
protectID();
setTitle("Update User");
switch ( action ) {
case RefreshEvent.CREATE:
case RefreshEvent.UPDATE:
break;
case RefreshEvent.DELETE:
break;
default:
break;
}
}
}
// In method, ’createDocument’
.
.
.
if( object != null ) {
RefreshEvent evt = new RefreshEvent( object,
RefreshEvent.CREATE );
RefreshService.getRefreshService().dispatchRefresh( evt );
}
.
.
.
Online Help
Windchill provides help classes that allow you to register an application with the
online help system and create keys that are associated with the online help that is
to be displayed. The following example links frames to help classes to provide
online help for those frames. For example, under the comment line:
//Add help topics
the line:
helpContext.addComponentHelp(btnUsers,"UserAdmin");
associates the key "UserAdmin" with the Users button. The resource bundle at the
end of the example, AdminHelpResources, links the key with the help that should
be displayed for that button.
//These packages are needed for online Help
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import wt.help.*;
//End of online help imports
//Localize
localize();
//{{DECLARE_MENUS
//}}
package wt.clients.administrator;
import java.util.*;
import java.lang.*;
public class AdminHelpResources extends java.util.
ListResourceBundle
{
public Object getContents()[][]
{
return contents;
}
//——-User Administration——-
{"Contents/Administrator/UserAdmin", "contents.html"},
{"Help/Administrator/UserAdmin", "FAQ.html"},
{"Desc/Administrator/UserAdmin", "User Admin default"},
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
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
default value. In most cases you will want to remove the user-level preference and
not clear it, giving the user the upper hierarchal preference as their default.
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).
Design Overview
The batch container package is generic and does not require the target objects to
be of any particular class. Within Windchill applications, batch containers are
generally used to batch groups of Persistable objects for server-side processing.
The batch container package provides no default server-side capability. The
developer must implement the service required for their particular purpose. The
External Interface
In addition to the types already mentioned, the container.batch package includes
the following types.
The RoleBatchContainer interface is a special purpose BatchContainer used to
accumulate associative assertions. In addition to the functionality provided by
type BatchContainer, the RoleBatchContainer carries information about the
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 is meant to replace the functionality provided by the
GatewayURL class. The GatewayURL class has several drawbacks including no
support for relative HREFs, as all values returned are in the form of an URL
which must be constructed and there is no support for remapping resources. As
well, in complex SPOC configurations the hostname of the Windchill server may
not be the hostname of the machine which sends the final page to the client, and
thus currently links generated through firewalls can only work if IP masquerading
and other techniques are used to fool the servers into redirecting the request
properly.
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.
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();
Forcing a Fully Qualified Link With a URLFactory that has a Non-null Request URI
A small caveat has been discovered with usage of the URLFactory. If the
developer wants 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. How can this be
achieved- The usage of the getHREF( ) methods that include the boolean switch
will do this by optionally setting the URLFactory into fully-
qualifiedmode'forthedurationofthemethod.ThisallowsasingleHREFtobegenerated
withoutaffectingtherestoftheURLFactory.LikeallgetHREF()methodsthereareform
softhemethodswhichtakequerystringsandarguments'
<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: To find out more about the EncodingConverter class, please refer to the
Windchill Javadoc.
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()
<% [ ]
// 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 )
{
% [ ]>
Topic Page
Background .......................................................................................................11-2
The Windchill Approach ...................................................................................11-2
Localizing Text Visible to the User ..................................................................11-4
11-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"},
//Localize
localize();
//{{DECLARE_CONTROLS
//}}
//{{DECLARE_MENUS
//}}
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"));
import java.util.ListResourceBundle;
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.
An example of resource bundles being used in online help is given in the
preceding chapter on developing client logic.
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.
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
three 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.
Note: The following sections describe the resource info files for Message Text.
ResourceInfo.customizable=false
ResourceInfo.deprecated=false
The first line classifies the resource info and should never be changed. The values
of the second to lines can be changed by the owner of the package, if the file can
be customized, and/or the file is deprecated.
Key Description
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
The Import Export Chapter describes the IX Framework and explains how to
customize and use it for various solutions.
Topic Page
Overview ...........................................................................................................12-2
How to Write an IX Application .......................................................................12-2
Exporter Class ...................................................................................................12-4
Using the Exporter to Export Objects ...............................................................12-7
How Import Works............................................................................................12-8
Importer class ..................................................................................................12-11
Use Importer to import object from XML files...............................................12-13
Writing Export Handlers for the Export Process.............................................12-16
How to write Exp/Imp Handlers .....................................................................12-16
DTD Files ........................................................................................................12-18
How to Write Handlers for the Import Process...............................................12-21
How to Write a Class (Element) Import Handler............................................12-22
Navigating Through an Object’s Structure with ObjectSet Application.........12-28
List of Existing Generators and Filters............................................................12-33
Examples .........................................................................................................12-33
Simple Export Handler Code: .........................................................................12-39
12-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.
Constructor:
Exporter (ApplicationExportHandler _applicationExportHandler,
String targetDTD,
IxbElement localMappingRules,
File policyRuleFile) throws WTException {
super ("export", localMappingRules);
// -- init expActionTuner --
applicationExportHandler = _applicationExportHandler;
dtd = targetDTD;
// -- init expActionTuner --
expActionTuner = new ExportActionTuner (policyRuleFile);
}
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. Currently, there are two DTD
strings that are used in Windchill 6.2.2:
standard.dtd: DTD for Windchill 6.0
standard62.dtd: DTD for Windchill 6.2
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="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>
For example the policy rule file specifies that check out exported WTPart objects
in the database after exporting them. If an exported WTDocument object has the
number of “TESTDOC-1”, check it out after exporting it. With all other exported
WTDocuments, lock them in the database after exporting them.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform
version="1.0">
<xsl:template match='*'>
<xsl:apply-templates select='WTPart'/>
<xsl:apply-templates select='WTDocument'/>
</xsl:template>
<xsl:template match='WTPart'>
<ACTION>Checkout</ACTION>
</xsl:template>
<xsl:template match='WTDocument'>
<xsl:choose>
<xsl:when test="number='TESTDOC-1'">
<ACTION>Checkout</ACTION>
</xsl:when>
<xsl:otherwise>
<ACTION>Lock</ACTION>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
If you don’t want to override anything, just pass “null” for the argument
policyRuleFile.
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);
}
You can call clean-up methods of appHandler (if there are any). Now the export is
finished.
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:
<actionInfo>
<xsl:choose>
<xsl:when test="criteria='value'">
<action>CreateNewObject</action>
<actionParams>
<newName>New Name</newName>
<newNumber>New Number</newNumber>
<newVersion>New Version</newVersion>
<newIteration>New Iteration</newIteration>
</actionParams>
</xsl:when>
<xsl:otherwise>
<action>Some other action</action>
</xsl:otherwise>
</xsl:choose>
</actionInfo>
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. Currently, there are two DTD strings that
are used in Windchill 6.2.2:
standard.dtd: DTD for Windchill 6.0
• ruleFileName: From windchill 6.2.6, mapping rule file can be XML file
(like in previous versions) or XSL file, so this parameter is String. The
constructor that uses IxbElement _localMappingRules is deprecated. In the
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
importer.finalizeImport();
doImport (doc)
This method doesn’t really import the object, but inserts the XML document that
represents the object in to a list to be imported later. After all XML documents
representing all the imported objects are inserted in the import list, the real import
process starts with the call to finalizeImport().
• finalizeImport(): The import process is actually performed in this
method. It will call to:
doImport_CheckConflicts() - check conflicts for imported objects.
After getting the handler for the element, the importElement(…) calls the
following methods:
handler.importElement(…) to do the import task.
For Windchill 6.2.6, 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:
createObject (fileXML, importer);
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>standard62.dtd</dtd>
<targetTag>default</targetTag>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</classExporter>
<classExporter>
<class>wt.part.WTPartUsageLink</class>
<dtd>standard.dtd</dtd>
<targetTag>default</targetTag>
<handler>
wt.ixb.handlers.forclasses.ExpImpForWTPartUsageLink
</handler>
</classExporter>
and in Windchill\src\wt\ixb\registry\ixb\handlers\
core62.xml, there are tags:
<classExporter>
<class>wt.part.WTPartUsageLink</class>
<dtd>standard62.dtd</dtd>
<targetTag>default</targetTag>
<handler>
wt.ixb.handlers.forclasses.ExpImpForWTPartUsageLink
</handler>
</classExporter>
DTD Files
For backward compatible support, in the folder Windchill\src\wt\ixb\registry\ixb\
dtds, there are 2 folders:
standard.dtd contains DTD files for Windchill 6.0
In each folders there is a file named coreobjects.dtd that is the DTD file for
all objects that will be exported/imported. For example, in the file
coreobjects.dtd in the folder standard.dtd, we can see the definition
for EPMDocument in R6.0:
<!ELEMENT EPMDocument (
ObjectID,
(ownerApplication , authoringApplication, description?) ,
(number, name ) , epmDocType , genericFamilyInstance? ,
(extentsValid , EPMBoxExtents)? ,
folderPath , versionInfo? , lifecycleInfo? , projectIdentity ,
contentItem*, iba* ) >
MyClass ob = (MyClass)object;
// export the local id
IxbHndHelper.exportAttribute(
ExpImpForLocalIdAttr.class, ob, fileXML, exporter);
// export other attributes that are specific to
// MyObject; e.g. name, number
IxbHndHelper.exportAttribute(
ExpImpForMyObjectAttr.class, ob, fileXML, exporter);
// export version information
IxbHndHelper.exportAttribute(
ExpImpForVersionAttr.class, ob, fileXML, exporter);
// export content
IxbHndHelper.exportAttribute(
ExpImpForContentAttr.class, ob, fileXML, exporter);
}
catch (Exception e) {
LogHelper.devExc ( e,
"exportAttributes: could not export
object=<"+object+">");
}
}
or
<classExporter>
<class>com.mycompany.MyObject</class>
<dtd>standard62.dtd</dtd>
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>standard62.dtd</dtd>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart</handler>
</elementImporter>
All handlers with the <dtd> tag “standard.dtd” are handlers for import
object in R6.0. All handlers with the <dtd> tag “standard62.dtd” are
handlers for import object in R6.2.
For example, to import parts from XML that came from R6.0, we have tags:
<elementImporter>
<tag>WTPart</tag>
<dtd>standard.dtd</dtd>
<handler>wt.ixb.handlers.forclasses.ExpImpForWTPart60</handler>
</elementImporter>
<elementImporter>
<tag>WTPartUsageLink</tag>
<dtd>standard.dtd</dtd>
<handler>
wt.ixb.handlers.forclasses.ExpImpForWTPartUsageLink
</handler>
</elementImporter>
In Windchill\codebase\registry\ixb\handlers\core62.xml, there
are the following tags:
<elementImporter>
<tag>WTPartUsageLink</tag>
<dtd>standard62.dtd</dtd>
<handler>
wt.ixb.handlers.forclasses.ExpImpForWTPartUsageLink
</handler>
</elementImporter>
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>standard.dtd</dtd>
<handler>com.ptc.mypackage.ExpImpForMyObject</handler>
</ elementImporter >
or
<elementImporter>
<tag>MyObject</tag>
<dtd>standard62.dtd</dtd>
<handler>com.ptc.mypackage.ExpImpForMyObject</handler>
</ elementImporter >
For Windchill 6.2.6, import handlers for versioned objects don’t have to
implement the method public Object storeObject (…) anymore. It is
implemented in the class ExpImpForVersionedObject.
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.
When an object is given to the export process, ObjectSet application will do the
job of navigating through the object’s structure and collecting all its related
objects. For example, when one WTPart is given to the export process, the
ObjectSet application will navigate through the product structure to see all parts
that are used by it, all “referenced” documents and the “described-by” document.
The definition of the navigation is taken from a set of XML files known as
navigation rule files. (Don’t confuse with the mapping rule files that are used to
override/change/exclude object’s attributes in Export and Import processes).
Additionally the 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.
Combining these Generators and Filters together, the application that wants to
export object will be able to create a set of objects that will be exported based on
given top-level object.
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>
Available Filter Id-s are defined in XML files in the folder Windchill\
codebase\registry\ixb\object_set_handlers with the tag
<setFilter>. A list of these Filter Ids can be obtained by calling to
IXBHelper.service.getAllAvaiableFilters(). It returns all
available Filters in the system.
IXBHelper.service.getFilterList() returns a list of Filters that will
be displayed to the GUI for user selection. This function help to hide filters which
you don’t want the end user to see. To hide such Filters, set the value of the
<display> tag to false in the XML files of these Filters.
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, please use the
method ObjectSetHelper.getAllAvaiableGenerators().
All the methods get…Generators and get…Filters return Vectors that
contain an element list of the type IXBHandlerDescription. Use getId()
of those elements to get lists of Generators or Filters that are passed as arguments
generatorIds and filterIds for the method doExport() in the
StandardIXBService.
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>
<rule>
<for>wt.part.WTPartDescribeLink</for>
<go>
<fromForeignKey>
<targetClass>wt.doc.WTDocument</targetClass>
<getMethodName>getDescribedBy</getMethodName>
</fromForeignKey>
</go>
</rule>
…
</schema>
The example above shows both possible types of navigation: From WTPart it
instructs to navigate to the wt.part.WTPartDescribeLink by a navigate
method and from there using 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. Here 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>
Examples
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>,
a given like:
Cabinet/Folder
wt.folder.Subfolder:1
(including
234 or
subfolders)
wt.folder.Cabinet:
1234
productStructureNavi Collects all children Product Structure <class name: oid>,
gator of a given Part (built with active like:
Config Spec)
(e.g. Parts, which it wt.part.WTPart:1234
uses and Documents for the top-level
which describe it) object. This object
must be instance of
WTPart
productStructureNavi Collects all children CAD Document <class name: oid>,
gatorEPM of a given CAD Structure (built with like:
Document active config spec)
wt.epm.EPMDocume
nt:1234 for the top-
level object. This
object must be
instance of
EPMDocument
Collects all children Product Structure <class name:oid>,
of a given Part with CAD documents like:
productStructureNavi
including related (built with active
gatorWithEPM wt.part.WTPart:1234
CAD Documents Config Spec)
for the top-level
object. This object
must be instance of
WTPart
Export Application
The current Windchill Export OOTB GUI and the StandardIXBService is an
Export Application.
The OOTB 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.
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 OOTB 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;
jw.addEntry(is, storeName);
}
catch (IOException ioe){
throw new WTException(ioe);
}
return storeName;
}
public void storeDocument (IxbElement elem)
throws WTException{
try {
String tag = elem.getTag();
String fn = NAME_IS_TAG+"-"+tag+"-"+(fileNum++)+".xml";
File file = new File(targetDir,fn);
FileOutputStream stream= new FileOutputStream (file);
elem.store(stream, IxbHelper.STANDARD_DTD);
stream.close();
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,
IxbHelper.STANDARD_DTD, clientSettingsElement, null, actionName );
}
else{
exporter = IxbHelper.newExporter (this,
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) {
if ( !(actionName != null &&
actionName.equals(wt.ixb.tuner.ExportActionHelper.NO_ACTION_CMD)
)){
trx.rollback();
}
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);
}
catch(IOException ioe){
throw new WTException(ioe);
}
}
public void storeLogMessage(String resourceBundle, String
messageKey, Object[] textInserts)
throws WTException{
WTMessage m = new WTMessage(resourceBundle, messageKey,
textInserts);
log.println(m.getLocalizedMessage());
}
public void doImport( File ruleFile, File dataFile, boolean
_overrideConflicts,
String actorName, File policyFile)
throws WTException{
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);
Topic Page
About the xconfmanager Utility........................................................................13-2
About the Windchill Command ........................................................................13-5
13-1
About the xconfmanager Utility
The xconfmanager is a command line utility that you can run to add, remove, or
modify properties in any Windchill property file. With one exception, the
following files are managed by Windchill Information Modeler and should not be
edited manually or edited with the xconfmanager:
• associationRegistry.properties
• classRegistry.properties
• descendentRegistry.properties
• modelRegistry.properties
The xconfmanager utility saves your changes in the site.xconf file and provides an
option to generate updated property files using the updates in the site.xconf file.
The site.xconf file contains the changes made to Windchill property files starting
with the 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 xconfmanger 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 and property files under the Windchill
installation directory can successfully run the xconfmanager utility. The
xconfigmanger is executed from the command line from within a windchill shell
See About the windchill Command chapter for more information about the
windchill shell.
The syntax of xconfmanager command is as follows:
xconfmanager {-FhuwvV} {-r <product_root>} {-s <property_pair>
{-t <property_file>}} {--reset <property_names>}
{--undefine <property_names>} {-d <property_names>} {-p}
For the purposes of modifying Windchill properties, you will primarily use the set
(s), targeFile (t), and propagate (p) parameters.
• set is used to define the property and new property value. See the Formatting
Property Value Guidelines section (below) for information about formatting
the <property_pair) value.
• targetFile is used to specify the directory location of the property file. If the
file name or path contains spaces, you must enclose the <property_file> value
in double quotes (" "). It is recommended to use a fully-qualified file name to
ensure an accurate reference to the file is made.
• propagate is used to propagate the changes made to the XCONF files into the
property file being modified in order to keep the XCONF and the property
files in synch with one another.
• To display the current settings for a property, execute the following command
from the windchill shell:
xconfmanager -d <property_names>
On a UNIX system, you can use doubles quotes or you can escape the space
character with a backslash. For example, use the following:
-s wt.inf.container.SiteOrganization.name=ACME\ Corporation"
On UNIX, dollar signs are usually interpreted by shells as variable prefixes. To set
a property value that has a dollar symbol in it, use single quotes around the
argument so that it is not interpreted by the shell or use backslash to escape the
dollar symbols. For example, use either of the following:
or
-s wt.homepage.jsp=
‘\$(wt.server.codebase)/wtcore/jsp/wt/portal/index.jsp
Other than escaping arguments so that the command line shell does not
misinterpret them, the values should not need to be escaped any further to be
compatible with XML or property file syntaxes. The xconfmanager escapes
property names and values automatically if necessary.
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 Actions
Action Description
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
User Authentication Framework ........................................................................A-2
Reference Implementation (HTTP authentication) ............................................A-5
Null Authentication ............................................................................................A-7
A-1
User Authentication Framework
The primary goal of the authentication framework is to allow each client-to-server
RMI call to be reliably, securely, and efficiently associated with an authenticated
user name by the server. A secondary goal is to be simple and extensible so that a
number of implementations are possible, including the reference implementation
described later in this appendix. To achieve these goals, the framework consists of
three key interfaces that partition responsibilities as follows:
• Endorsing individual RMI calls (the wt.method.MethodAuthenticator
interface).
• Securely and reliably determining user name (the
wt.auth.AuthenticationHandler interface).
• Validating endorsed calls, associating them to a user name (the
wt.auth.Authenticator interface).
Each of these interfaces is described below. The wt.method package contains the
Windchill method server application main class, and it owns the basic client-to-
server calling mechanism. The wt.auth package builds on the basic framework
provided by the wt.method package to add more authentication specific support
classes.
wt.method.MethodAuthenticator
The Windchill method servers provide a dynamic method invocation interface
that is accessed through a non remote class called
wt.method.RemoteMethodServer. This class exposes an invoke method but
encapsulates the details of accessing a remote method server. It hides the actual
RMI operations in order to add network failure recovery and authentication
support. The invocation target and all the call arguments are passed in an
argument container class called wt.method.MethodArgs. This argument container
contains a field for arbitrary authentication information.
The basic method invocation framework does nothing with this field. Instead, it
allows for an arbitrary server-supplied object (a wt.method.MethodAuthenticator)
to endorse outgoing calls. This object can set the extra field or wrapper the entire
wt.method.MethodArgs object such that deserialization on the server-side actually
initializes the extra field. The requirement is simply that when argument
deserialization is complete, a server-side authenticator object can use the
credentials in this extra field to reliably determine the caller’s user name.
The client receives a wt.method.MethodAuthenticator object inside a special
Throwable, wt.method.AuthenticationException, sent from the server when
authentication is required. The client automatically handles this exception by
initializing the received wt.method.MethodAuthenticator and using it to endorse a
retry of the failed call. Once installed, it continues to endorse all calls from that
client.
The wt.method.MethodAuthenticator interface consists of the following methods:
wt.auth.AuthenticationHandler
The method server does not hard-code what authentication scheme will be used to
securely and reliably determine user names. Instead, the wt.auth package supports
a configuration property, wt.auth.handlers, that specifies a list of classes that
implement an authentication handler interface, wt.auth.AuthenticationHandler.
The class wt.auth.Authentication is responsible for making the client’s
authenticated user name available for the higher-level application layers to take
advantage of. It has a static method called getUserName that is used to access the
authenticated user name for the current thread. If the client call being processed
by the current thread did not pass any authentication information, it asks the first
wt.auth.Authenticator
In order to keep the initial (bootstrap) login authentication separate from
subsequent per-call authentication, a third interface, wt.auth.Authenticator, and
another configurable property, wt.auth.authenticator, are used to validate
endorsed calls. This allows several login techniques to share the same per-call
endorsement technique and allow them to be developed independently.
When a bootstrapping authenticator has determined the authenticated user name
of a client, the bootstrapping authenticator can be replaced by one returned by the
wt.auth.Authentication class’s newMethodAuthenticator method. This method
Null Authentication
The wt.auth.NullAuthentication class, another authentication handler provided in
the Windchill base product class allows standalone applications running on the
same host as the Windchill method server to authenticate using their user.name
Java system property. It can be used to allow standalone administrative
applications, such as install/load tools, to execute even if the built-in
authentication schemes supported by the wt.httpgw.HTTPLogin class are not
sufficient for the local Web server environment.
It checks against the client’s IP address to determine if it is a local client. If so, it
sends a wt.auth.NullLogin object to the client which accesses the user.name Java
system property. It will not access the Java system properties if a security
manager is in effect. In other words, it does not try to authenticate browser-based
clients, even if they are running on the local host. It is intended only to
authenticate stand-alone administrative applications.
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 ................................................................ B-2
The Business Service Design Pattern................................................................. B-3
The Master-iteration Design Pattern .................................................................. B-6
B-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.
The ServiceException abstraction provides a common definition of an exceptional
condition that may occur as a result of abnormal behavior in the service. This
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.
QuerySpec
The QuerySpec contains the following attributes and APIs for building complex
query expressions.
C-1
with zero or more classes in the From clause. See the following table to determine
the size of the a_fromIndices array based on the type of ColumnExpression. For
example, a single ClassAttribute would require one from index. A SQLFunction
with two ClassAttribute arguments and a ConstantExpression argument would
require two from indices. If no fromIndices are required, a null value can be
passed as the argument. The selectOnly parameter controls whether the column
expression should be returned as a result object. If true, the column expression is
included only in the select and is not returned as a result.
The ColumnExpression parameter specifies the query column to append to the
select clause. The following are concrete ColumnExpression implementations:
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
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)));
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
does not exist. An alternate is represented by the WTPartAlternateLink class,
which is a many-to-many association between PartMasters. The role A of the
WTPartAlternateLink class specifies the current PartMaster and the role B
specifies the alternate PartMaster. Following is the SQL for this query:
SELECT A0.*
FROM WTPartMaster A0
WHERE NOT (EXISTS (SELECT B0.ida2a2
FROM WTPartAlternateLink B0
WHERE (A0.ida2a2 = B0.ida3a5)))
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
Bind Parameters
Bind parameters are a database/JDBC feature to take advantage of database
statement preparsing and optimization. Bind parameters are a mechanism for
replacing constants in a SQL statement with replacement parameters at execution
time. For example, the following WHERE clause expression uses the constant
’Engine’:
WTPartMaster.name = ’Engine’
This expression can be replaced with the following in the static SQL:
WTPartMaster.name = ?
and the value ’Engine’ can be bound to the parameter ? at execution time.
On a subsequent execution, a new value, such as Cylinder, can be bound to that
same parameter. If these two statements had used the constant value directly in the
static SQL, each statement would have been parsed, optimized, and precompiled
separately. When bind parameters are used, a single static SQL statement can be
reused multiple times.
This bind parameter feature is implicitly supported when using the QuerySpec,
SearchCondition, and other query classes. However, the bind parameters can also
be explicitly accessed using the following APIs:
getBindParameterCount()
getBindParameterAt(int a_index)
setBindParameterAt(Object a_value, int a_index)
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
SearchCondition
A SearchCondition represents a SQL WHERE clause expression of the following
form:
<left side operand> <operator> <right side operand>
The following are examples:
MyTable.Column1 = 5
MyTable.Column2 LIKE "E%"
MyTable.Column3 = JoinTable.Column1
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 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 });
Finally, the compound statement is constructed using the two previous queries
and the UNION set operator.
CompoundQuerySpec compound = new CompoundQuerySpec();
compound.setSetOperator(SetOperator.UNION);
compound.addComponent(partSelect);
compound.addComponent(altSelect);
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
Topic Page
Background Information ....................................................................................D-2
General Externalization Guidelines....................................................................D-3
Hand-coded Externalization Guidelines.............................................................D-3
Migration Guidelines for Classes with Hand-coded Externalization.................D-4
Examples of Generated Externalization Code for Evolvable Classes................D-4
D-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.
Background Information
As of Release 4.0, the generated externalization code reads and writes a data
stream according to the following order, with field values for each class ordered
alphabetically:
1. BottomClass.ID
2. MiddleClass.ID
3. TopClass.ID
4. TopClass field value1
5. TopClass field value2
6. TopClass field value...N
7. MiddleClass field value1
8. MiddleClass field value2
9. MiddleClass field value...N
10. BottomClass field value1
11. BottomClass field value2
12. BottomClass field value...N
output.writeLong( EXTERNALIZATION_VERSION_UID );
super.writeExternal( output );
output.writeObject( a1 );
output.writeObject( a2 );
output.writeObject( a3 );
output.writeObject( list );
output.writeObject((size==null - null:size.getStringValue()) );
output.writeObject( timeline );
output.writeObject( work );
a1 = (String)input.readObject();
a2 = (Date)input.readObject();
a3 = (Xyz)input.readObject();
list = (Vector)input.readObject();
String size_string_value = (String)input.readObject();
return success;
timeline = (Timeline)input.readObject();
work = (MyAddress)input.readObject();
}
else if ( !superDone ) {
success = super.readVersion( this, input,
readSerialVersionUID, false, false ); // reformatted stream-
This appendix describes the GUI design process used to create the user interface
of Windchill applications. Although you are not required to follow this process to
create applications with Windchill, we recommend that you use some formal
design method. Even if you have already started design, you can use this process
to validate your work.
Topic Page
Overview of the Design Process ........................................................................ E-2
Gather User Requirements ................................................................................. E-4
Analyze Tasks .................................................................................................... E-6
Design the GUI................................................................................................. E-13
E-1
Overview of the Design Process
There are three major phases in the design process, each of which contains
specialized tasks that are described in more detail later in this appendix.
The first steps in the GUI design process are to define the users and their
requirements. Profiles of the users and their requirements are used as input when
modeling user tasks and GUI objects. They are also used during the GUI
evaluation step to validate the prototype.
Task structure models and task object models can be used as input to each other.
Task structure models are used to identify objects within the tasks, and the
resulting objects can be used to validate the task structure models. Both are then
used as input to the GUI design step.
A highly desirable input to the GUI design is a UI style guide, which also
addresses internationalization concerns. Use (or develop) your own corporate
style guide, use one already written for the platform for which you are designing,
or use one of the many available commercially.
The last phase, actual development of the GUI, is an iterative process of designing
the GUI, developing a prototype, evaluating the prototype, and then redesigning
Requirement Priority
Requirement Priority
Analyze Tasks
A task is a human activity that achieves a specific goal. Examples of tasks are:
creating a document, finding a file, generating a bill of materials, or updating user
information.
Modeling user tasks starts with very simple, brief descriptions of individual tasks
and evolves to detailed descriptions of how the user interacts with the system.
Modeling tasks involves the following steps:
General
Incident Reports
Product Information
Every user requirement previously defined should be accounted for in the use
cases (although this slide is a subset and may not show every entry actually in the
use cases).
User requirements, however, do not have to map to use cases one-to-one. For
example, the two user requirements shown earlier:
• Make inquiry about product user is registered for.
• Make inquiry about any existing product.
Develop Storyboards
A storyboard is based on one or more task scenarios. It is a sequence of images,
usually drawn by hand on paper, that show interactions with the system and a
sequence of screens. For example, the first image may be the action "log on" and
the next image could be a screen labeled "Initial logon screen".
The sequence of screens conveys information about structure, functionality, and
navigation. This information can be used in developing prototypes and validating
user requirements.
Typically a storyboard is done in two columns with the images in the first column
and explanatory text in the second column. The following figure is an example of
Storyboard Example
The objects described in the model must be represented on the screen. Creating a
task object model helps you create objects that map directly to user tasks.
Creating a task object model is also an important step in streamlining the user
interface. Following the model will result in an interface that contains every
object needed to accomplish user tasks-and nothing more.
Index-1
db directory, 1-2 Executable class files, 1-4
db.properties file
Database access properties, 1-10 F
General description, 1-8
wt.pom.dbPassword property, 1-11 Federation package, 6-21
wt.pom.dbUser property, 1-11 Folder resident business class, 5-4
wt.pom.serviceName property, 1-11 Foldering package, 6-24
Debug tracing, 1-9 FolderPanel bean, 10-35
debug.properties file Windchill Foundation classes
General description, 1-8 Definitions, 3-10
Development environment
Directory structure, 1-2 G
Environment variables, 1-7
Files, 1-2, 1-5 GUI
Property files, 1-8 Design process, E-1
Source code control, 1-6
Directory H
bin, 1-2
codebase HTML files
Details of, 1-4 Location of, 1-5
Location, 1-2 HTTP authentication, A-5
codebase/wt, 1-5 HTTPUploadDownloadPanel bean, 10-57
db, 1-2
docs, 1-2 I
loadFiles, 1-2
logs, 1-2 IDEs, 10-3
RoseExtensions, 1-2, 1-7 Indexing package, 6-34
search, 1-2 Integrated development environment
src See IDEs
Details of, 1-5 Internationalization, 11-1
Location, 1-2 Item class, 3-10
src/wt, 1-6
Structure after installation, 1-2 J
Doc package, 5-10
docs directory, 1-2 Java beans
Document class, 5-10 AssociationsPanel, 10-29
Document package, 5-10 AttributesForm, 10-37
Domain administration package, 6-7 EffectivityPanel, 10-33
EnumeratedChoice, 10-24
FolderPanel, 10-35
E HTTPUploadDownloadPanel bean, 10-57
EffectivityPanel bean, 10-33 PartAttributesPanel, 10-18
Enterprise package, 5-2 PrincipalSelectionBrowser, 10-51
EnumeratedChoice bean, 10-24 PrincipalSelectionPanel, 10-46
Environment variables Spinner, 10-28
Class path, 1-7 ViewChoice, 10-43
Rational Rose virtual path map, 1-7 WTChooser, 10-23
SQL path, 1-7 WTContentHolder, 10-7
Events WTExplorer, 10-11
Managing, 8-3 WTMultiList, 10-28
Examples WTQuery, 10-21
Development process, 2-1 java.rmi.server.hostname property, 1-9
JSP
Index-3
Q Notification, 6-43
Organization, 6-46
QueryResult, 7-15 Overview, 6-1
QuerySpec, 7-13 Ownership, 6-47
Query, 7-12
R Session management, 6-57
Version control, 6-64
Rational Rose, 3-2 Work in progress, 6-84
Virtual path map, 1-7 Workflow, 6-87
Windchill extensions, 1-2, 1-7 Session management package, 6-57
WT_EXTENSIONS entry, 1-7 Sharing code, 1-6
WT_STD_PACKAGES entry, 1-7 Signed authentication, A-7
WT_WORK entry, 1-7, 1-10 Simple business class, 5-2
RB.java files Source code management, 1-6
Location of, 1-5 Source files, 1-2, 1-5, 1-6
Refreshing client data, 10-66 Spinner bean, 10-28
Resource bundles SQL path environment variable, 1-7
Localizing, 11-4 SQL scripts, 1-2
Location of, 1-5 Location, 1-10
Online help, 10-68 SQLPATH environment variable, 1-7
Revision control, 5-6 src directory, 1-2
Revision controlled business class, 5-6 Details of, 1-5
Rose model components, 1-6 System generation
RoseExtensions directory, 1-2, 1-7 Overview, 9-1
Runtime environment Using, 9-41
Files, 1-2, 1-4
T
S
Task logic, 10-3
search directory, 1-2 Threading, 10-64
SearchCondition, 7-14 tools.properties file
Server logic General description, 1-8
Overview of developing, 8-1 Use by code generator, 1-10
Server manager wt.classRegistry.search.path property, 1-10
Logging trace messages, 1-9 wt.classRegistry.search.pattern property, 1-10
service.properties file wt.generation.bin.dir property, 1-10
General description, 1-8 wt.generation.source.dir property, 1-10
Services wt.generation.sql.dir property, 1-10
Access control, 6-4 wt.generation.sql.xxxTablesSize property, 1-10
Background queuing, 6-50 ToolsSetup.bat, 1-2
Batch containers, 10-73 Trace logs
Configuration specification, 6-73 Default location, 1-2
Content handling, 6-8 Trace messages
Content replication, 6-14 Logging
Domain administration, 6-7 From method server, 1-9
Event management, 8-3 From server manager, 1-9
Federation, 6-21 Training materials
Foldering, 6-24 Location, 1-2
Indexing, 6-34 Transactions, 7-16
Life cycle management, 6-36
Locking, 6-41
Managing, 8-2
W
Windchill extensions, 1-2
Work in progress package, 6-84
Workflow package, 6-87
wt directory
See also Packages
wt.access.enforce property, 1-9
wt.classRegistry.search.path property, 1-10
wt.classRegistry.search.pattern property, 1-10
wt.generation.bin.dir property, 1-10
wt.generation.source.dir property, 1-10
wt.generation.sql.dir property, 1-10
wt.generation.sql.xxxtablesSize property, 1-10
wt.home property, 1-8
wt.logs.enabled property, 1-9
wt.manager.verboseClient property, 1-9
wt.manager.verboseServer property, 1-9
wt.method.verboseClient property, 1-9
wt.method.verboseServer property, 1-9
wt.pom.dbPassword property, 1-11
wt.pom.dbUser property, 1-11
wt.pom.properties property, 1-10
wt.pom.serviceName property, 1-11
wt.properties file
Double back slashes in path names, 1-8
Format of path names, 1-8
General description, 1-8
java.rmi.server.hostname property, 1-9
wt.access.enforce property, 1-9
wt.home property, 1-8
Index-5