Creating reusable patterns with Imported Model and profiling
This sample shows an example of a reusable high-level pattern implemented in a "base model" which is profiled to provide parameterization of inputs. This technique can be very valuable if you have a number of portlets that are very similar. You can implement the common functionality in a single place (in a “base” model), and then create any number of parameterized and customized versions. Imported Model is used to bring in the base model and to set parameterized inputs, using the option for "Set Individual Inputs". With that option, the "calling" model can specify values for the profiled inputs.
In the example here, the base model creates a simple view of data from a service provider. The base model contains three builders, but you can use as many builders as you want in a base model. There are four inputs that are profiled in this sample:
• Service Consumer builder - Provider Model input (so you can point to any data provider)
• View and Form builder - View Data Operation and Paged Data Display inputs
• Text builder - Text input
There are two sample models that use the base model with the Imported Model builder: ProfiledServiceOrders and ProfiledServiceEmployees. Note that in these models you can add any builders you like to to enhance or customize the functionality. Both samples have builders added such as Data Field Settings, and the "Orders" sample includes builders that add a "create" page and button.
To view these samples you will need the "Tutorials and Samples / Building Models" feature set in your project, since it has the OrdersServiceProvider model.
Here is the Imported Model builder showing the profiled inputs:
Here is the running model, using the XmlImportProvider set in the profiled inputs:
Making a model-based builder from a profiled Imported Model
This sample pack also includes a model-based builder that has been made from the profiled imported model. To create the builder, Builder Skeleton was used, as in the ServiceViewBuilderSkeleton model. This generated all the needed builder files. The only editing that was then done to the generated files was in the bdef - the "base" attribute was set for the ProviderModel and ViewMethod inputs. This was done to obtain the correct pickers for those inputs.
Note that when using the builder, you have to click "OK" (or "Apply") in the builder whenever you change the provider model input. This is needed in order to see the updated choices for "View Method". This issue can be addressed with some Coordinator code at some point.
Here is a screenshot of the model-based builder:
Here is the running model, showing the data from OrdersServiceProvider – note that this single builder generates the complete data view functionality, and you can now add any builders that modify or add functionality such as Data Field Settings, Data Layout, Theme, etc.:
Sample files for profiled Imported Model:
ProfiledBaseModel.model - base model with profiled inputs
profiled_service_ps.pset - profile set used in sample
ProfiledServiceOrders.model - sample using Imported Model
ProfiledServiceEmployees.model - another sample using Imported Model, with a different provider
XmlImportProvider.model - A sample provider that just returns data from an XML file
Employees.xml - XML file for XmlImportProvider
Sample files for custom model-based builder:
ServiceViewBuilderSkeleton.model - contains Builder Skeleton used to generate builder files
ServiceViewBuilder.bdef - generated bdef, with edits described above
ServiceViewBuilder.java - generated builder class (extends Imported Model)
ServiceViewCoordinator.java - generated Coordinator class
ServiceViewOrders.model - sample using the custom model-based builder
ServiceViewEmployees.model - another sample using the custom model-based builder
Some comments about using this model-based builder approach vs. a Java custom builder
Anything that you do with a model-based builder can also be done with a Java builder. The Java builder would just have to invoke all the builders that are used to implement the pattern, and the builder code would need to set all the needed inputs for the builders that are used. In some ways a Java builder is simpler to understand, since the Java code explicitly calls all the builders and sets the builder inputs. However, a model-based builder can let you make a change to the base model (for example, adding a builder) that is automatically reflected wherever the model-based builder is used. With a Java builder you have to explicitly add code for any updates to functionality. Within the WEF team we use both approaches. Typically we might use a model-based builder for the high-level builders such as View And Form or Data Services User Interface.