Base Class and Derived Class Combination
JPOs ship as a combination of a base class and a derived class.
For
example, the JPO responsible for Part related business logic is delivered
as the combination of a base class named emxPartBase and a derived class
named emxPart. The JPO naming convention consists of prepending emx in
front of the Bean name and appending Base on the base class name.
Out-of-the-box business logic always goes into the base JPO. This
code is owned and managed by ENOVIA. Any extensions should be placed
into the derived JPO where it will be automatically preserved when new
releases of the applications are installed.
For extensions to be picked up, all references to JPO methods made
by the system (either from Beans, triggers, or dynamic UI components)
go through the derived JPO. If there are no extensions in the derived
JPO, the base JPO functionality is picked up through inheritance.

Extending a JPO Method
The basic way to extend a JPO method is to write a method in the derived
JPO that exactly matches the signature of an existing method in the base
JPO.
The derived method can call the base method (using super.methodName())
if you want to have the method add additional logic to what ships out
of the box. If the derived method never calls the base method, the result
is that the derived method completely replaces what ships out of the
box.
Use the derived JPO technique to ensure your customizations are preserved
when new releases, service packs, and hot fixes are installed. The key
is to isolate your modified logic into the derived JPO (as opposed to
modifying the OOTB code directly). The installation routines do not copy
derived JPOs into the database, if they already exist so there is no
chance of losing your modifications.
Methods called in the base JPO may have code changes, but their APIs
remain consistent, so there should never be a case where your derived
JPO no longer compiles after installing a new release. However, you may
want to determine if any of the JPO methods you have extended changed
in the base JPO and decide what impact these changes might have on your
customization. If you copied code from a base JPO (not recommended),
you may have to manually update the code.
The source code of your derived JPO should always be backed up in
a source control system.

JPO Hierarchy
This section shows an example JPO hierarchy.

To be consistent with the existing naming conventions, emxPartBase should
really be emxEngineeringPartBase, and emxPart should really be emxEngineeringPart.
For historical reasons, some JPO names are named different than the current
convention.

Extending Beans
The need to extend Beans decreases as more and more business
logic is moved from the Beans into JPOs. However, when you have to extend
a Bean, there is a mechanism in place that allows you to derive a Bean
from an existing Bean and have the system use the derived Bean.
You can write your own class within an application using the same
name as the common class and have your class extend the common class.
Since these classes share the same name, take special care on import
statements to avoid wildcards. Otherwise you may need to fully qualify
the class references throughout the code. ENOVIA recommends that you
use the wildcard on import statements for your application classes, but
avoid the wildcard on import statements for common components classes.
Mapping File
After defining your derived Bean class, you need to change the entry
in the appropriate mapping file to indicate that newInstance should serve
up an instance of your class instead of the out-of-the-box class.
For example, suppose you extend the Part Bean in the engineering.jar
file and name your new class com.acme.apps.engineering.AcmePart. The
entry:
type_Part=com.matrixone.apps.engineering.Part should be changed to:
type_Part=com.acme.apps.engineering.AcmePart The modified mapping file can then be placed back into
the jar file from which it came or it can be placed in the properties
directory in the application server (since these are searched ahead of
the jar files).
Extending a Bean Method
The basic way to extend a Bean method is to write a method in the derived
Bean that exactly matches the signature of an existing method in the
base Bean.
The derived method can call the base method (using super.methodName())
if you want to have the method add additional logic to what ships out-of-the
box. If the derived method never calls the base method, the derived method
completely replaces what was originally shipped.
To extend a Bean:
- Write a new class that extends the Bean (that is, derives from the out-of-the-box
Bean found in one of the jar files). You can place the compiled code
for this new class anywhere that is defined on the classpath.
- Update the mapping file that specifies which Bean to use for a given
business type or relationship type. The WEB-INF/classes directory is
always searched before WEB-INF/lib (per Java spec), so this is a good
place for Bean code to reside.
Each package has a mapping file where each Bean in that package is
registered. For example, the Part Bean lives in both common and engineering.
There is an entry in each mapping file.
- In engineering: type_Part=com.matrixone.apps.engineering.Part
- In common: type_Part=com.matrixone.apps.common.Part.
Each bean maps to the appropriate package.
The Search Path
The method DomainObject.newInstance() searches for the appropriate Bean
based on the given type or object id.
- If an application is given, the search begins in that application's
mapping file. While searching for a match, the type hierarchy found in
the schema is used to return the closest match.
- If no match is found, the search moves to the common mapping file.
If no match found, the method returns a DomainObject. For example, if
no BracketPart or Part is found in the Engineering Central mapping file (say, for example
it was removed), then the common mapping file would be searched (and
if no BracketPart is in there, it would return a common Part).
- If the common mapping file had no Part entry, a DomainObject is returned.
Eventually there will be a DomainObject.SYMBOLIC_type_BracketPart
constant.
The key is to isolate your new classes and modified mapping file from
being written over by new changes from ENOVIA. The installations do not
install mapping files in the WEB-INF/classes directory so there is no
chance of a clash. However, you will want to extract a new mapping file
from the newly deployed jar file in case there have been modifications
made since the prior release. It should be straight forward to update
your mapping file and place the changed file back into the WEB-INF/classes
directory.

Extending JSPs
Java filters can be used to handle extensions to JSPs to preserve them across new releases of the ENOVIA products.
JSP filters
let you intercept requests based on a URL pattern and perform alternative
logic. Filters can be chained, which allows the results of one filter
to be passed as input to a subsequent filter. To do this, place a copy the JSP in a special directory.
This leaves the original JSP intact in its original directory. This section presents these topics:
JSP Filters
JSP Filters were first made available in J2EE application
servers which implement the Servlet 2.3 specification.
The following
table shows the minimal version of each application server.
Server Name |
Minimum Version |
WebLogic |
6.1 |
WebSphere |
5.0 |
SunOne |
7.0 |
The ENOVIA Live Collaboration Server contains the CustomFilter class. This filter has been designed to look
for a JSP:
- With the same name as the one found in the current URL, but located
in a subdirectory named custom (by default).
- With the name defined by the ematrix.customDirName parameter.
- With a name that is the concatenation of a specified prefix (with
ematrix.customPrefix) and the name in the requested URL.
The filter information is configured using web.xml (found in the WEB-INF
directory). The class is commented out in the web.xml file shipped with
the ENOVIA products.
If you uncomment this class, filtering is activated and any custom
JSPs takes control. To restore the system to its original out-of -the
box state, just comment out this section and restart the server.
You can turn on just the URL pattern of interest to improve performance
since the filter only comes into play when the appropriate url pattern
is matched. All other URLs pass through the system in a normal fashion
(that is, with no filtering).
Refer to the Live Collaboration BPS Installation Guide
for details on configuring filtering.
The use of CustomFilter will ensure your customizations are preserved
during the installation of new releases, service packs, and hot fixes.
- One option of CustomFilter places all of your modified JSPs in a separate
directory. This makes it easy to backup your code and manage your code
during upgrades. The downside is the need to modify paths in the JSP.
- The other option relies on a common prefix associated with your custom
JSPs. With a simple grep-like command, you can easily find the custom
pages from among the OOTB pages. New JSPs dropped into
the system during an upgrade will never overwrite your custom JSPs. However,
you will have to manually merge changes from the new OOTB JSPs back into
your custom JSPs. One way to simplify this would be to diff the incoming
JSPs with the originals to isolate which JSPs have changed and what those
changes were. This delta change could then be analyzed and a determination
made on how to incorporate the changes into your custom JSPs.
Resources
Java filters can transform a Request, or modify a Response to the items listed in this section.
Java filters can be used to:
- intercept a servlet's invocation
- examine a request before a servlet is called
- modify the request headers and request data
- modify the response headers and response data.
See "Taming your Tomcat: Filtering tricks for Tomcat 5" for an example
of how to use filters in the most recent Servlet 2.4 specification. http://www-106.ibm.com/developerworks/java/library/j-tomcat2/#N400061.
|