Jump to: navigation, search

Customize Templates and Replication


With UBIK®, it is possible to replicate (basically, copy and paste) objects and even complex object hierarchies, based on a template configuration.

This article explains what options you have to enable this and how to do it in your project customizing.



[edit]

Instructions

First, it is important to understand that there are two approaches for templates and replication:

  • Client side replication
  • Server side replication

Client side replication

In case of client side replication, the mobile client application provides a Copy and a Paste button that can be used to replicate an object directly in the app.

For this, you have to add the Templatable Data Classification to the ACM context scope of the MetaClass you want to be templatable.

It is important to note that the ISTEMPLATE property of this classification has some interesting implicit behavior: If the lock status of this property is set to read-only in the ACM scope, all other properties will be read-only, too. If you don't want the user to modify the ISTEMPLATE property, but you need them to modify other properties, just set the visibility of ISTEMPLATE to hidden, but leave the lock status at read-write.

Also, if you want to paste an object somewhere, the respective ACM scope must be a possible child of the parent scope. So, you have to configure the ACM to allow the copy to be pasted below the new parent object.


Server side replication

In case of server side replication, you can use programmatic customizing to trigger the replication of complex object structures, including relations or references, files, and of course, instances and properties.

For this, you first have to configure a ReplicationConfiguration. There are different types of replication configurations, for different purposes, as described in the article about the replication configuration. Choose the one you need and create an instance of it in UBIK® Studio. Then, you can configure the details (e.g., which properties to copy) in the relation editor for the configuration object.

Finally, you need to create some custom code actually executing the replication. For example, let's say we want to copy an object when it is saved. You have to fetch the replication configuration and the thing you want to replicate. Then, you can call the replicate method of the configuration object, with the replication target as a parameter. The result will be a collection of replicated objects.

The respective code could look like the following (example from a real project):

protected override void OnPrepareForSave(UBIK.Kernel.ObjectUpdatedEventArgs e)
{
        //***UBIK customized code for OnPrepareForSave.
        //***Initial edited on 06/09/2021 16:48:03

        if(this.MP_DUPLICATE_ME && this.ISTEMPLATE)
        {
                Guid rep_configID = new Guid("1a8982bf-7447-44ad-8850-b0e174ed4f10"); //IRC_OPERATOR_ROUNDS            
                UBIK.Content.ContentClass rep_config = this.Environment.UBIKDataFactory().ContentObject(rep_configID);
                RelationalObject rep_source = (RelationalObject) this;                                 
                UBIK.Kernel.Replication.InstanceReplication repl = (UBIK.Kernel.Replication.InstanceReplication) rep_config;
                UBIK.Kernel.Replication.ReplicationResult rep_Result = repl.Replicate(rep_source);     
               
                if((rep_Result != null) && (rep_Result.Root != null))
                {
                        UBIK.Runtime.OPERATOR_ROUNDS opr = (UBIK.Runtime.OPERATOR_ROUNDS) rep_Result.Root;                     
                        if(this.MP_DUPLICATE_IS_TEMPLATE)
                        {
                                opr.Name = this.Name + "_NEW_TEMPLATE";                        
                                foreach(UBIK.Runtime.OPR_BASECLASS rep_Item in rep_Result.AllItems())
                                {
                                        rep_Item.ISTEMPLATE = true;
                                }
                        }
                        else
                        {
                                opr.Name = this.Name + "_INSTANCE";
                        }
                       
                        foreach (BaseClass rep_Item in rep_Result.AllItems())
                        {
                                this.AddToUnsavedChildren(rep_Item);
                        }
                }              
        }
        this.MP_DUPLICATE_ME = false;
        this.MP_DUPLICATE_IS_TEMPLATE = false;
        base.OnPrepareForSave(e);
}

See also