Provider encapsulation

Voici une bonne pratique pour l’intégration d’une vue dans une étape d’un assistant (wizard). Pour le bon fonctionnement du développement, il est préférable que les providers des deux écrans puissent se connaître et interagir.

Il s’agit de l’exemple d’une inclusion d’une vue dans un assistant, mais la modélisation proposée pourrait aussi bien être réalisée dans le cas d’autres types d’écrans avec une inclusion entre eux.

Est proposée ici non seulement une solution, mais une bonne pratique de modélisation pour qu’à chaque implémentation de ce type d’inclusion d’écran, la même logique soit respectée.

Conception XML

<wizard name="simple01" action="browse" label="LG_SIMPLE01_LABEL" information="LG_SIMPLE01_INFORMATION" provider="com.vdoc.ui.providers.MyWizardProvider">
	<pages>
		<page name="page1" label="LG_PAGE1_LABEL" information="LG_PAGE1_INFORMATION" default="true">
			<content>
				<view name="simple01" action="view" label="" provider="com.vdoc.ui.providers.MyViewProvider" sortable="false" filterable="false">
					<column name="col01" label="LG_COL01" />
					<column name="col02" label="LG_COL02" />
				</view>
			</content>
		</page>
		<page name="page2" label="LG_PAGE2_LABEL" information="LG_PAGE2_INFORMATION" >
			<fields>
			</fields>
		</page>
	</pages>
</wizard>

Conception Java

Provider père

Il s’agit de l’assistant (wizard), qui a plusieurs travaux à gérer :

  • Initialiser une map des sous-écrans
  • Avoir accès à tous les sous-écrans directement

Exemple d’un provider père du wizard :

public class MyWizardProvider extends BaseWizardProvider {
    protected Map<String, IProvider> childProviderMap;
    
    public MyWizardProvider(INavigateContext context, AbstractDocument document, CtlAbstractWizard abstractWizard) {
        super(context, document, abstractWizard);
        childProviderMap = new HashMap<>();
    }

    /**
     * @see com.axemble.vdp.ui.core.providers.IWizardProvider#activate(com.axemble.vdp.ui.framework.composites.base.ISection)
     */
    @Override
    public void activate(ISection section) {
        // For each step of wizard, we try to initialize child screens :
        // - Depending on screens, we initialize screen
        // - We get reference to child providers
        // - We set ourself as reference in child providers
        childProviderMap.putAll(IncludedScreensUtil.initializeChildScreens(this, section.getContent()));
    }

    /**
     * @see com.axemble.vdp.ui.core.providers.base.AbstractDocumentProvider#readyState()
     */
    @Override
    public void readyState() {
        super.readyState();

        // Example here : we can get one of child providers : myclass.mymethod
        IProvider childViewProvider = childProviderMap.get("simple01.view");
    }
}

Provider fils

Il s’agit de la vue, qui va seulement avoir un attribut de classe nommé parentScreen. Cet attribut possédera des assesseurs en GET et SET. Ces méthodes seront décrites dans une interface IChildProvider.

Interface et exemple d’un provider fils de vue :

public interface IChildProvider {
	public abstract IProvider getParentProvider();
	public abstract void setParentProvider(IProvider provider);
}
public class MyViewProvider extends BaseViewProvider implements IChildProvider, ICollectionModelViewProvider {
    protected IProvider parentProvider = null;
    
    public MyViewProvider(INavigateContext context, CtlAbstractView view) {
        super(context, view);
    }

    /**
     * @see com.vdoc.ui.providers.interfaces.IChildProvider#getParentProvider()
     */
    @Override
    public IProvider getParentProvider() {
        return parentProvider;
    }

    /**
     * @see com.vdoc.ui.providers.interfaces.IChildProvider#setParentProvider(com.axemble.vdoc.sdk.interfaces.runtime.IProvider)
     */
    @Override
    public void setParentProvider(IProvider provider) {
        this.parentProvider = provider;
    }

    /**
     * @see com.axemble.vdp.ui.core.providers.ICollectionModelViewProvider#getModelItems()
     */
    @Override
    public List<ViewModelItem> getModelItems() {
        // Example : we can call here our parent provider to get data...
        // getParentProvider()...

        return null;
    }
}

Classe utilitaire

/**
 * Used to initialize child screens and link them
 */
public static Map<String, IProvider> initializeChildScreens(IProvider parentProvider, Widget content) {
	Map<String, IProvider> providerMap = new HashMap<String, IProvider>();
	
	CtlAbstractNavigation abstractNavigation = null;
	if (content instanceof CtlAbstractNavigation) {
		abstractNavigation = (CtlAbstractNavigation)content;
		
		// We get reference on child provider
		providerMap.put(abstractNavigation.getContext().getClassName() + "." + abstractNavigation.getContext().getMethodName(), abstractNavigation.getProvider());
		
		// We set ourself as reference on child provider
		if (abstractNavigation.getProvider() instanceof IChildProvider) {
			IChildProvider childProvider = (IChildProvider)abstractNavigation.getProvider();
			childProvider.setParentProvider(parentProvider);
		}
		
		// Initialization of child screens
		if (content instanceof CtlAbstractView) {
			IViewProvider viewProvider = ((CtlAbstractView)content).getProvider();
			viewProvider.init();
			viewProvider.getColumns();
			viewProvider.getItems();
		}
		// Else... We could handle other screens types
	}
	return providerMap;
}

Source : https://wiki.myvdoc.net/xwiki/bin/view/Dev+Floor/HowToIncludeAViewInAWizard