ADF : parcourir les enregistrements d'une ViewObject master-detail (Ière méthodologie avec SetCurrentRowWithKey)

Cet articles sera découpé en 2 parties, chacune présentant une méthodologie pour le parcours d’un ensemble d’enregistrements d’une vue maître-détail de façon programmée (la méthode sera appelée iterateOverMasterDetailRecords()) dans le ViewControllerProject.
A partir de là, chacun pourra customizer ce code en appliquant son traitement aux enregistrements récupérés de la vue maître et/ou détail.
Dans ce premier article, nous étudierons le cas utilisant la built-in method d’ADF SetCurrentRowWithKey.
Dans le second article, nous utiliserons le ViewLinkAccessor existant entre les 2 vues.

Point de départ

On considère une page jspx sur laquelle a été bindée deux DataControls reliés par un lien master-detail (un ViewLink les associe).
On crée dans le ManagedBean de la page la méthode iterateOverMasterDetailRecords().

Méthodes utilitaires utilisées

Nous ferons appel dans les 2 articles aux méthodes utilitaires ADFUtils.findIterator(), ADFUtils.getBindingContainer() et JsFUtils.resolveExpression() de Steve Muench et Duncan Mills permettant de récupérer l’iterator d’une collection d’objets.

/**
 * Find an iterator binding in the current binding container by name.
 *
 * @param name iterator binding name
 * @return iterator binding
 */
 public static DCIteratorBinding findIterator(String name) {
     DCIteratorBinding iter = getDCBindingContainer().findIteratorBinding(name);
         if (iter == null) {
	     throw new RuntimeException("Iterator '" + name + "' not found");
         }
      return iter;
 }
/**
 * Return the Binding Container as a DCBindingContainer.
 * @return current binding container as a DCBindingContainer
 */
 public static DCBindingContainer getDCBindingContainer() {
     return (DCBindingContainer) getBindingContainer();
 }
/**
 * Return the current page's binding container.
 * @return the current page's binding container
 */
 public static BindingContainer getBindingContainer() {
     return (BindingContainer) JsfUtils.resolveExpression("#{bindings}");
 }
/**
 * Method for taking a reference to a JSF binding expression and returning
 * the matching object (or creating it).
 * @param expression EL expression
 * @return Managed object
 */
 public static Object resolveExpression(String expression) {
     FacesContext facesContext = getFacesContext();
     Application app = facesContext.getApplication();
     ExpressionFactory elFactory = app.getExpressionFactory();
     ELContext elContext = facesContext.getELContext();
     ValueExpression valueExp = elFactory.createValueExpression(elContext,
     expression, Object.class);
    return valueExp.getValue(elContext);
 }

Implémentation du parcours des enregistrements

Cette première partie de la méthode sert à parcourir les enregistrements de la vue maître.

/**
 * Permet de parcourir les enregistrements d'une vue maitre-détail.
 */
public String iterateOverMasterDetailRecords() {
     // Iterateur de la table maitre
     DCIteratorBinding masterViewIt = ADFUtils.findIterator("
     masterViewIterator");
     // Iterateur de la table details
     DCIteratorBinding detailsViewIt = ADFUtils.findIterator("
     detailsViewIterator"));
     // RowSetIt de la vue maitre :  on utilise un RowSetIterator secondaire
     // pour que le traitement n'influence pas l'affichage de la page.
     RowSetIterator masterViewRowSetIt =
     masterViewIt.getViewObject().createRowSetIterator(null);
     // On se positionne sur le slot avant la premiere ligne
     masterViewRowSetIt.reset();
     // RowSetIt de la vue details
     RowSetIterator detailsViewRowSetIt =
     detailsViewIt.getViewObject().createRowSetIterator(null);
     detailsViewRowSetIt.reset();
     // Ligne en cours de la vue maitre
     Row masterCurrentRow = null;
     // Ligne en cours de la vue details
     Row detailsCurrentRow = null;
      // Parcours de la vue maitre
      while (masterViewRowSetIt.hasNext()) {
          masterViewRowSetIt.next();
      	  // Recuperation de la ligne en cours de la vue maitre
      	  masterCurrentRow = masterViewRowSetIt.getCurrentRow();
      	  // Ici votre code pour travailler sur la vue maitre
      	  // Par exemple, on peut vouloir recuperer un attribut de la masterView
      	  Object masterAttribute = masterCurrentRow.getAttribute("
          monMasterAttribut");

Ci-dessous, le point central du fonctionnement de cette méthode, on applique à l’itérateur de la vue maître la built-in method ADF SetCurrentRowWithKey.

           // On positionne l'iterator de la vue maitre sur la ligne actuelle
	   masterViewIt.setCurrentRowWithKey(masterCurrentRow.getKey().toStringFormat
           (true));

Celle-ci prend pour paramètre la Key (currentRow.getKey().toStringFormat(true)) de la ligne convertie sous forme de String.
Elle a pour effet de positionner l’itérateur de la vue au niveau de la ligne dont on lui a passée la Key, qui devient alors la ligne en cours.
Ce faisant, du fait que cette vue maître est liée à une vue détails par un ViewLink, l’application du SetCurrentRowWithKey a pour effet de mettre à jour les données de la vue détails en les restreignant aux enregistrements correspondants à la ligne maître devenue la ligne en cours. (par application d’une where clause à la vue détails sur la ou les colonnes servant de lien entre les deux).
Sans cela, vous n’auriez fait que parcourir les enregistrements de la vue détails correspondants à la première ligne de la vue maître (positionnement par défaut de l’itérateur), autant de fois qu’il y a de lignes dans la vue maître.
De la même façon que pour la vue maître, on peut alors parcourir les enregistrements de la vue détails pour la ligne maître en cours.

	    // Parcours de la vue details
            while (detailsViewRowSetIt.hasNext()) {
                detailsViewRowSetIt.next();
        	// Recuperation de la ligne en cours de la vue details
        	detailsCurrentRow = detailsViewRowSetIt.getCurrentRow();
        	// Ici votre code pour travailler sur la vue details
        	// Par exemple, on peut recuperer un attribut de la detailsView
        	Object detailsAttribute = detailsCurrentRow.getAttribute("
                monDetailsAttribut");
      	    }
 	}

Au terme de ce code, vous avez bien parcouru :

  • toutes les lignes de la vue maître
  • toutes les lignes de la vue détails leur correspondant

2 réflexions sur “ADF : parcourir les enregistrements d'une ViewObject master-detail (Ière méthodologie avec SetCurrentRowWithKey)”

  1. Ping : ADF : parcourir les enregistrements d’une ViewObject master-detail (IIème méthodologie avec le ViewLinkAccessor) | EASYTEAM

  2. Ping : ADF : parcourir les enregistrements d’une ViewObject master-detail (IIème méthodologie avec le ViewLinkAccessor) « EASYTEAM LE BLOG

Les commentaires sont fermés.