Transition fields - Group name (<structure system>, <language>)
This article applies to the Heiler Product Manager in versions 6.0 and above.
Overview
A new column is available in the Item table and Product table views as well as a new field in the detail views of item and product. Its name is "Group name (<structure system>,<language>)" for example "Group name (Heiler Standard, English)" and it shows the names of all structure groups an article/product is assigned to. This column is analogous to the column structure assignments, but instead of showing the structure groups' identifier it shows its name. The order of the entries in both columns may vary and the values are not editable! In all other matters it acts like the structure assignments column. In the field selection dialog the logical keys of this field are set to client language and the primary structure tree as set in the preferences dialog by default.
Implementation
The challenge of the group name field is that a field of entity StructureGroup should be displayed in a view restricted to the entity Article.
To make the display of this information as well as the data retrieval possible, we introduced a new kind of field called transition field. It enables you to transition from one entity to another via a proxy.
The feature we implemented was the group name field. The feature we implemented was NOT TransitionFields! You CAN use TransitionFields, but if you do so you must be aware that there might be things not working as expected. There are still methods in the TransitionFieldWrapper which are not implemented or if implemented maybe they suit another use case but had to be more sophisticated to also suit your case. There are views being "special" and not handling everything like all the other views and this might lead to problems with TransitionFields. Noone knows!
Transition Fields
Transition fields are always read-only.
Newly created transition fields should work with FieldBasedTableViews and FieldBasedFormViews as long as the rootEntityType of the transition matches the entityType of the view. This means, that it won't work with Views displaying data of a certain subentity (for example the view Item references with its entity ReferencedArticle).
Repository
To use a transition, you have to add a new transition field to the repositories' custom area. You'll find the transition field somewhere is the custom area. It is neither a child node of the source entity nor of the target entity.
The source entity (the entity you want to start at) which is the article entity in the group name example, needs to have a field with a Proxy Transition Entity entry to the entity where your information you want to reach is located.
The transition field consists of
identifier
name
source field - the field containing the Proxy Transition Entity
target field - the field containing the content you want to reach
TransitionFields for Item/Product/Variant references view - Version 8 and later
The Item references view shows data about all references the item may have to products, items and variants. It is a special implementation because it shows these data in a shared column, although technically in our data model it is stored in three different subentities which would normally require three different columns for the three different fields. It is a fact that item does have some fields, products and variants don't have. We want the customer to be able to show these data in the view, hence we changed the entity of the view to ArticleReference for the item reference view, to Product2G2ArticleReference for products and Variant2ArticleReference for variants.
What does it mean for your Transition fields?
It means that you have to use fields in these entities as the source Field and a field of item as the target field. These Transition fields will show data of referenced items, products and variants.
TransitionFieldWrapper and TransitionEntityPath
The resulting new class which is generated due to the repository changes is the TransitionField. To use this field as a Field in tables and detail views there's the class TransitionFieldWrapper which implements the Field interface and forwards requests to either the source field or the target field.
In PIM 6 when TransitionFields were introduced, it was common practice that consultants adapted the code by themselves if their requirements forced a different behaviour. Therefore only the methods needed for the group name field were initially implemented in the TransitionFieldWrapper.
With PIM 7 the situation changed and there should no longer be changes of the standard code base. When TransitionFields were used more and more, more and more UnsupportedOperationExecptions occurred which now couldn't be fixed by the consultants. To meet these concerns the API Request was created and all methods in the TransitionFieldWrapper will be implemented and documented. Probably the implementation will be part of the Servicepack 7.0.05.
NOTE : The implementation is done to the best knowledge. However, for some methods not all cases in which they are called are known in detail, so it is not possible to check if its behaviour is always adequate. There might be default implementations which are too simple for a use case of a customizing.
In general most getter will return the information from the target field (in some cases from the source field and in some cases from the transition field itself). Most setter methods will throw an UnsupportedOperationException (or will do nothing) because it is not desirable to change another field by a call to the transition field. There are methods to access the source and target field. If possible use these and call the method on those fields.
For more details have a look at the Javadoc.
If you need a FieldPath from one entity to another, you can use the TransitionEntityPath. In this case there need not be an explicit Transition field in the repository.
The TransitionEntityPath consists of a FieldPath to the field containing the Proxy Transition Entity entry which leads to the destination entity (proxyFieldPath) and an EntityPath from the root of the destination entity to the (but not including) the destination field (destEntityPath). The destination field itself is part of the enclosing FieldPath.
Here is an example of a field path from article to StructureGroupLangType.Name in XML:
<field-path
sys-id=
"1"
sys-type=
"dp"
sys-
class
=
"com.heiler.ppm.repository.path.FieldPath"
dest-field-type=
"StructureGroupLangType.Name"
>
<transition-entity-path
sys-id=
"1"
sys-type=
"dp"
sys-
class
=
"com.heiler.ppm.repository.path.TransitionEntityPath"
dest-field-type=
"ArticleStructureMapType.StructureGroupProxy"
start-entity-type=
"StructureGroupType"
dest-entity-type=
"StructureGroupLangType"
revision-token=
"1"
>
<entity-path
sys-id=
"1"
sys-type=
"dp"
sys-
class
=
"com.heiler.ppm.repository.path.EntityPath"
start-entity-type=
"ArticleType"
dest-entity-type=
"ArticleStructureMapType"
revision-token=
"1"
>
<logical-key
type=
"ArticleStructureMapType.LK.StructureId"
value=
"10011"
/>
</entity-path>
<logical-key
type=
"StructureGroupLangType.LK.Language"
value=
"7"
/>
<logical-key-filter
type=
"StructureGroupLangType.LK.Language"
>
<filter-
enum
>Enum.Language</filter-
enum
>
</logical-key-filter>
</transition-entity-path>
</field-path>
The proxyFieldPath consists of the entityPath from line 16 to 27 and the dest-field-type entry in line 11. This describes the path from Article (root) to ArticleStructureMapType.StructureGroupProxy. The value for the logical key of the structure system can also be found here (line 24-26)
The path in the destination entity type StructureGroupType is defined by the destEntityPath which is the entityPath in the transition-entity-path element (line 12-14) and lines 2-4 of the field element which define the destination field. Note that the logical key for the language is part of the destEntityPath and is therefore found in the transition-entity-path (lines 29-36).
The code to construct this FieldPath is the following:
EntityType articleType = RepositoryUtils.getRepositoryEntityType(
"Article"
);
EntityType articleStructureMapType = RepositoryUtils.getRepositoryEntityType(
"ArticleStructureMapType"
);
EntityPath entityPath =
new
EntityPath( articleType, articleStructureMapType );
entityPath.setLogicalKeyValue(
"ArticleStructureMapType.LK.StructureId"
, 10011L );
String proxyFieldTypeIdentifier =
"ArticleStructureMapType.StructureGroupProxy"
;
FieldPath proxyFieldPath =
new
FieldPath( entityPath, proxyFieldTypeIdentifier );
EntityType structureGroupLangType = RepositoryUtils.getRepositoryEntityType(
"StructureGroupLangType"
);
TransitionEntityPath transitionEntityPath =
new
TransitionEntityPath( proxyFieldPath, structureGroupLangType );
transitionEntityPath.setLogicalKeyValue(
"StructureGroupLangType.LK.Language"
, 7L );
String destFieldTypeIdentifier =
"StructureGroupLangType.Name"
;
FieldPath fieldPath =
new
FieldPath( transitionEntityPath, destFieldTypeIdentifier );
Corresponding to the TransitionEntityPath, also a CustomTransitionEntityPath is available. (The CustomTransitionEntityPath is working on Entities whereas the TransitionEntityPath is working on EntityTypes.)
Fragment Manager
The FragmentManager handles the fragments which are the items knowing how to retrieve the requested data from the database.
Before HPM 6.0, transitions were only possible with non virtual ListModels and no list values of transitions were supported. To change that a bigger refactoring in the area of the FragmentManager was necessary. The transition handling moved from the loadListModel method to the execute method. The TransitionHandlers are working on FragmentDataRows and not on ListModelEntries anymore to support the virtual loading. The TransitionFragmentMerger has been introduced. It merges the transition ListModel in the base ListModel including the handling of list values meaning the transition ListModel contains multiple lines which will become a list value in the resulting ListModel. Some changes in the FragmentDataRow implementations were made to support the sorting of transition fields in a virtual ListModel.
Extension Point for changed logical key default values
In the field selection dialog, normally the default values for the fields' logical keys are taken from the default values in the repository (if any).
If this is not the desired behaviour there's a new extension point called com.heiler.ppm.std.ui.fieldSelectionDialogLogicalKeyInitializer which enables you to change these values.
You can register a field type identifier together with a class implementing the interface com.heiler.ppm.std.ui.dialog.repository.logicalkeyinitialization.FieldSelectionDialogLogicalKeyInitializer which is given a list of keys relative to the reference entity set by the field selection dialog.
Export
Before, if an item was assigned to multiple structure groups only one arbitrary group was picked out and became part of the export output. Now the whole list will be in the output.
Example :
{&Item.Structure groups.Name}
in the export template and qualified with the structure system will result in:
structure group 1; structure group 2; structure group3
if an item is assigned to these three structure groups