9 November 2014

 

CUSTOM COMPONENTS 

 

   Composite components limited to composing base jsf components

o   Custom components are how all of the base components were written and many libraries of sophisticated components such as ADFfaces, iceFaces, primeFaces, etc. 

o   valuable to see mechanics in order to get deep understanding of framework

   2 of a components main responsibilities are

o   Encode (generate markup)

o   Decode http requests

   Must subclass  UIComponent (or subclass)

o   UIOutput

o   UIInput

o   UICommand

 

 

 

 



   important categories of data managed by UIComponent p421-2

o   list of child components

o   map of facet components

o   map of attributes

o   collection of event listeners

 

 

 

 

 

1. All JSF custom components extend basic component classes such as UIComponent or its main subclasses UIInput, UIOutput, UICommand.  Science of Consciousness:  The process of transcending gives you the direct experience of how your Self is an extension of the most basic level of awareness, pure consciousness.



 

 

 

 



Spinner demo—how to use the tag 423

 

      xmlns:corejsf="http://corejsf.com">

            #{msgs.monthPrompt}

            <corejsf:spinner value="#{cardExpirationDate.month}"    id="monthSpinner" minimum="1" maximum="12" size="3"/>

 

            #{msgs.yearPrompt}

            <corejsf:spinner value="#{cardExpirationDate.year}"     id="yearSpinner" minimum="1900" maximum="2100" size="5"/>

 

 

 



Encoding:  generating markup

 

   markup generated

 

<input name="spinnerForm:monthSpinner" value="12" size="3" />

<input type="submit" name="spinnerForm:monthSpinner.less" value="&lt;" />

<input type="submit" name="spinnerForm:monthSpinner.more" value="&gt;" />

 

 

 

 

 

   3 methods, only 1 needed for spinner since no children

o   encodeBegin

o   encodeChildren

o   encodeEnd

 

 

   public void encodeBegin(FacesContext context) throws IOException {

      ResponseWriter writer = context.getResponseWriter();

      String clientId = getClientId(context);

 

      encodeInputField(writer, clientId);

      encodeDecrementButton(writer, clientId);

      encodeIncrementButton(writer, clientId);

   }

 

 

   private void encodeInputField(ResponseWriter writer, String clientId)  throws IOException {

      writer.startElement("input", this);

      writer.writeAttribute("name", clientId, null);

 

      Object v = getValue();

      if (v != null) writer.writeAttribute("value", v, "value");

 

      Object size = getAttributes().get("size");

      if (size != null) writer.writeAttribute("size", size, "size");

 

      writer.endElement("input");

   }

 

   private void encodeDecrementButton(ResponseWriter writer, String clientId)  throws IOException {

      writer.startElement("input", this);

      writer.writeAttribute("type", "submit", null);

      writer.writeAttribute("name", clientId + LESS, null);

      writer.writeAttribute("value", "<", "value");

      writer.endElement("input");

   }

 

   private void encodeIncrementButton( …

 

 

 

 

 

 

2. All components must override the encode method to generate the HTML markup to be sent in the HTTP response to the browser.  The framework calls this method on every component during the render response phase.  Science of Consciousness:  Encoding can be considered an outward stroke in which the JSF framework has supported an orderly response into activity—similar to the outward stroke of meditation in which your experience of quiet awareness supports orderly and successful activity.

 

 

 

 

 

 



Decoding:  processing http request

 

public void decode(FacesContext context) {

      Map<String, String> requestMap    = context.getExternalContext().getRequestParameterMap();

      /* get JSF generated component id */

      String clientId = getClientId(context);

 

      int increment;

      /* detect which button < or > was clicked  */

      if (requestMap.containsKey(clientId + MORE)) increment = 1;

      else if (requestMap.containsKey(clientId + LESS)) increment = -1;

      else increment = 0;

 

      try {

        /* get request value for this component */

         int submittedValue  = Integer.parseInt((String) requestMap.get(clientId));

 

         int newValue = getIncrementedValue(submittedValue, increment);

         setSubmittedValue("" + newValue);  //make it a String

      }

      catch(NumberFormatException ex) {

         // let the converter take care of bad input, but we still have

         // to set the submitted value, or the converter won't have

         // any input to deal with

         setSubmittedValue((String) requestMap.get(clientId));

      }

   }

  

   /* adds increment to value and takes into account min and max */

   private int getIncrementedValue(int submittedValue, int increment) {

      Integer minimum = toInteger(getAttributes().get("minimum"));

      Integer maximum = toInteger(getAttributes().get("maximum"));

      int newValue = submittedValue + increment;

 

      if ((minimum == null || newValue >= minimum.intValue()) &&

         (maximum == null || newValue <= maximum.intValue()))

         return newValue;

      else

         return submittedValue;

   }  

  

   /* value of minimum or maximum attributes could be set as String literal or  by a value expression, which might return a Number */

   private static Integer toInteger(Object value) {     

      if (value == null) return null;

      if (value instanceof Number) return ((Number) value).intValue();

      if (value instanceof String) return Integer.parseInt((String) value);

      throw new IllegalArgumentException("Cannot convert " + value);

   }

 

 

 

 

 

 

 

 

 

3.  All components must override the decode method to retrieve the input value for this component and save it as the method’s submittedValue.  Decode is called by the framework on all components during the apply request values phase.  Science of Consciousness:   Decoding can be considered an inward stroke which integrates the request into the structure of the framework—similar to the inward stroke of meditation that integrates our awareness into the structure of silent non-changing structure of pure consciousness.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

TLD  433-4

   Namespace

o   E.g. xmlns:corejsf=http://corejsf.com

o   Goes on the jsf page using the component

   Name of tag and component type

o   Type is an id that gets used with annotations

o   Identifies the class than implements the component

 

@FacesComponent("com.corejsf.Spinner")

public class UISpinner extends UIInput {

   private static final String MORE = ".more";

 

 

 

   Specify file location in web.xml p434

 

   <context-param>

        <param-name>javax.faces.FACELETS_LIBRARIES</param-name>

        <param-value>/WEB-INF/corejsf.taglib.xml</param-value>

    </context-param>

 

 

   Convention – file name ends in taglib.xml

 

 corejsf.taglib.xml

<facelet-taglib … >

   <namespace>http://corejsf.com</namespace>

   <tag>

      <tag-name>spinner</tag-name>

      <component>

         <component-type>com.corejsf.Spinner</component-type>  <!- -for tag handler annotation- - >     

      </component>     

   </tag>

</facelet-taglib>