< PreviousChapter 6: Solution180Figure 6.36: Run-Time Component Tree Visualization of “Architecture Fundamentals” (classical)Figure 6.35: Run-Time Component Tree Visualization of “Architecture Fundamentals” (natural)User Interface Run-Time Monitoring1816.13.2 Real-Time Component Tree TracingThe Component System, like ComponentJS, usually is a technical library providing bare Component management and communication mechanisms and especially has no knowledge about MVC/CT or even HUICA. As a consequence, the Compo-nent System has no knowledge about the Component Roles like View, Model or Controller or any patterns like Common Ancestor Communication. This is fine from a bare technical point of view but means that the application technically is able to perform more kinds of communication than it is allowed from an MVC/CT and HUICA architecture perspective. Hence, it can be reasonable to constrain the Component communication during run time, at least during application development.For ComponentJS a plugin named ComponentJS-Tracing provides such a con-straint mechanism. It can both real-time trace and real-time check the communica-tion and operation of the Component Tree (see Figure 6.37 on page 182). With it one can express both “peephole” and “temporal” constraints. Some examples from [Vaas 2014] follow. An example of a peephole constraint checking a coding conven-tion for Model Component value names can be: peephole-constraint prefix-check { rationale { The prefixes for model members have to be chosen according to their role within the presentation model. } condition { operation == “value” && !( startsWith(parameters.name, “param:”) || startsWith(parameters.name, “data:”) || startsWith(parameters.name, “state:”) || startsWith(parameters.name, “cmd:”) || startsWith(parameters.name, “event:”)) } result FAIL_FINAL }Another peephole constraint checking the correct life-cycle state usage can be:peephole-constraint plug-state-coupling { rationale { A view has to conduct its plug operations when it is in the materialized state. } condition { operation == “plug” && originType == “V” && state(origin) != “materialized” The Component System usually provides more communication possi-bilities than an architect wants to allow.CoChapter 6: Solution182Figure 6.37: Run-Time Tracing and Real-Time Checking with ComponentJS-TracingUser Interface Run-Time Monitoring183 } result FAIL_FINAL } In contrast to these peephole constraints, one can also express temporal constraints. These take the time into account and correlate more than one point in time. An example for checking the correct order of opera-tion observe() and value() on a Model Component can be: temporal-constraint observe-value { rationale { Value expects an observe beforehand, otherwise it would be useless. } sequence { a << b << terminate } filter a { operation == “observe” } filter b { operation == ”value” && parameters.value != undefined } link { a.parameters.name == b.parameters.name && isParent(a.origin, b.origin) } }Finally, a second temporal constraint for checking whether a model is defined be-fore it is used can be:temporal-constraint model-member-def { rationale { Model members have to be defined before they can be observed or accessed. } sequence { a << b } filter a { operation == “model” } filter b { operation == “observe” || operation == ”value” || operation == “touch” } link { isParent(a.origin, b.origin) Peephole constraints are easy to implement, but are limited. Temporal constraints are harder to implement, but provide a lot more possibilities.Chapter 6: Solution184 && contains(a.parameters, b.parameters.name) } }6.14 User Interface Run-Time IntegrationSimple things should be simple and complex things should be possible. — Alan KayIn practice, there are two classic situations where multiple User Interfaces (UI), or at least multiple foreign UI Fragments, have to be integrated during run time as seamless as possible for the user: ■Legacy Application: some remaining UI Fragments of an older application have to be integrated into the UI of the newer application. The older ap-plication nowadays is usually based on either the Thin-Client or Rich-Client architecture, while the newer application (in our context here) is assumed to be based on the Rich-Client architecture. ■Microservice Architecture: an application is vertically split into domain-specific Microservices (small applications having a small domain scope based on a certain Bounded Context according to Domain-Driven Design [Evans 2004]), each (in our context here) is assumed to be based on the Rich-Client architecture.As the target User Interface in our context is assumed to be based on the Rich Cli-ent architecture, HUICA and HTML5, there are two possible scenarios for integrat-ing the source User Interface.6.14.1 Rich-Client IntegrationAssuming the source User Interface (UI) is based on at least the Rich-Client archi-tecture and HTML5, according to its UI pattern approach we can choose different integration approaches: ■HUICA: The integration can be performed by loading the entire source ap-plication into the same browser context and integrate the two UIs directly on the Component-Tree level. The main issue here is that the source UI has to be forced to use exactly the same Component System instance, of course. This approach works only for strongly-related UIs, usually an older and a newer version of the same application. The communication between the source and target UI can directly happen on the (same) Component-Tree.User Interface Run-Time Integration185 ■Non-HUICA: The integration can be performed by representing the source UI with a single wrapping Component in the target UI and loading the en-tire source application into an HTML5 <iframe> on the target UI Compo-nent’s View Component. This approach works for all types of source UIs. The communication between the source and target UI have to leverage an Inter-Process-Communication (IPC) mechanism like HTML5 window.post-Message.6.14.2 Thin-Client IntegrationAssuming the source User Interface (UI) is based on the Thin-Client architecture and HTML5 (which is usually the case for legacy Java JSF applications in 2018), the integration can be performed by represent-ing the source UI with a single wrapping Component in the target UI and loading the masks of the source UI into an HTML5 <iframe> on the target UI Component’s View Component. This approach works for all types of source UIs. The communication between source and target UI have to lever-age an Inter-Process-Communication (IPC) mechanism like HTML5 window.post-Message. For this, the IPC mechanism has to be re-injected into every mask of the source UI, of course.Integrating a legacy Thin-Client based JSF UI into a new Rich-Client based HTML5 UI is technically possible, but it is a rather nasty integration and hence was named “Frank-enstein integration” in practice afterwards.186IVPartImplementation, Example, Experience and EvaluationChapter 7ImplementationNext >