Wednesday, February 29, 2012

Showing XML Payload In a Popup.

If you also have a requirement where you need to show XML content/payload stored in a CLOB column in the database on an ADF UI, like in a popup as shown below:



Then here are the steps you need to follow to configure a popup to show XML content nicely on the UI:

  1. Create a VO that contains that CLOB attribute.
  2. Create a popup with Content Delivery property set to 'LazyUncached'.
  3. Inside popup, put a Dialog (or panelWindow if you like with Modal property set to true).
  4. Inside Dialog, put a PanelFormLayout component.
  5. Inside PanelFormLayout component, drag the CLOB attribute as inputText component. Configure the inputText component as follows:    
    1. Set Read-Only as true, if you dont want the user to edit it, as in my case. 
    2. Set the Rows property to any value between 5 to 40 depending on how much payload you want to show on screen at once. 
    3. Set the Columns property to any value between 5 to 40 depending on how much characters in a row you want to show on screen at once. 
    4. Set Wrap property to 'soft'. 
    5. Set the Converter property to a customised converted, like ClobConverter (code shown below).
  6. Use ShowPopupBehavior operation as child of link/button to render the popup.

Here is how that popup code looks like:   

          <af:popup childCreation="deferred" autoCancel="disabled" id="p1" contentDelivery="lazyUncached">
            <af:dialog id="d1" type="cancel">
              <f:facet name="buttonBar"/>
              <af:panelBox text="B2b Payload*" id="pb1">
                <f:facet name="toolbar"/>
                <af:panelFormLayout id="pfl1">
                  <f:facet name="footer"/>
                  <af:inputText value="#{bindings.B2bPayload.inputValue}" label="#{bindings.B2bPayload.hints.label}"
                                required="#{bindings.B2bPayload.hints.mandatory}"
                                columns="100"
                                maximumLength="#{bindings.B2bPayload.hints.precision}"
                                shortDesc="#{bindings.B2bPayload.hints.tooltip}" id="it1" converter="ClobConverter"
                                readOnly="true" rows="21" wrap="soft">
                    <f:validator binding="#{bindings.B2bPayload.validator}"/>
                  </af:inputText>
                </af:panelFormLayout>
              </af:panelBox>
            </af:dialog>
          </af:popup>

    The ClobConverter looks like as shown below:

package com.emerson.eth.adf.view.converter;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

import javax.faces.convert.ConverterException;

import oracle.jbo.domain.ClobDomain;

public class ClobConverter implements Converter {
    public ClobConverter() {
        super();
    }

    public Object getAsObject(FacesContext context,
                              UIComponent component, String value) {
        if (context == null || component == null) {
            throw new NullPointerException("FacesContext and UIComponent can not be null");
        }

        if (value == null) {
            return null;
        }
        try {
            return new ClobDomain(value);
        } catch (Exception ex) {
            final String message =
                String.format("Unable to convert boolean value \"%s\" into a oracle.jbo.domain.Number",
                              value);
            throw new ConverterException(message, ex);
        }
    }

    public String getAsString(FacesContext context,
                              UIComponent component, Object value) {
        if (context == null || component == null) {
            throw new NullPointerException("FacesContext and UIComponent can not be null");
        }
        return value.toString();
    }
}

You need to register this converter in the faces-config.xml to make it visible in the inputText component configuration wizard, as shown below:

<?xml version="1.0" encoding="windows-1252"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee">
  <application>
    <default-render-kit-id>oracle.adf.rich</default-render-kit-id>
  </application>
  <converter>
    <converter-id>ClobConverter</converter-id>
    <converter-class>com.emerson.eth.adf.view.converter.ClobConverter</converter-class>
  </converter>
</faces-config>

NOTE:

For XML to appear in the UI, you also need to disabled the wrapping of LOBs done by the Web Logic Server at the data source level. To do this, un-check the 'wrap data type' check box available at:
WLS Home -> Data Sources -> DS used by the app -> Connection Pool -> Advanced.


3 comments:

  1. Thanks, this meets the exact requirement
    Best Regards,
    Vineet

    ReplyDelete
  2. Hello,

    I used the same code... but still my payload is not appearing in XML hierarchical format :(. Could you help?

    ReplyDelete