myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tadashi Enomori <tadashi.enom...@oracle.com>
Subject Re: Mobile Agents (Blackberry)
Date Mon, 30 Mar 2009 18:30:57 GMT
Hi Aurel,

Trinidad groups BlackBerry devices to two major groups. BlackBerry 4.5.x 
or lower (e.g. Curve and Pearl) or BlackBerry 4.6 (Bold) or higher 
(Storm is 4.7).
BlackBerry 4.5.x or lower does not support XMLHttpRequest (needed to run 
Ajax) and some capabilities are more restrictive than BlackBerry 4.6 or 
higher. The most significant restriction is the performance. Once 
JavaScript is used on these devices, the page load will take much longer 
and usability suffers from it. Not to mention the transfer time to 
download Trinidad's large JavaScript file. (Though it is cached and it 
is not a problem on subsequent page load, the initial page load will 
give negative user experience.) It was our decision not to use 
JavaScript fir BlackBerry 4.5.x or lower. (see 
http://myfaces.apache.org/trinidad/devguide/mobile.html#Basic_XHTML_Browser_Support, 
and 
http://myfaces.apache.org/trinidad/devguide/mobile.html#BlackBerry_4.5_Lower)
On the other hand, Blackberry 4.6 and higher has better performance. It 
supports XMLHttpRequest. Its JavaScript and DOM support are good. So we 
decided to enable JavaScript and Ajax partial page rendering. It is 
basically as functional as iPhone or even desktop browsers.

There are some Trinidad renderer logic that is specific to BlackBerty in 
order to supplement lack of JavaScript and CSS implementation in the 
BlackBerry browsers, but they are transparent to the application.

I have created some sample demo apps to test Trinidad mobile support. I 
did not need to do anything special, except for designing the UI to fit 
in a small screen - that is always the case for mobile UI development. 
There are some techniques/snippets that can be used for mobile web page 
development I can share with you if you are interested.

Use of skinning for different device types is useful in mobile 
development. See 
http://myfaces.apache.org/trinidad/devguide/mobile.html#Skinning for 
more info.

General info is at http://myfaces.apache.org/trinidad/devguide/mobile.html.

I have developed some sample demo apps. There are some techniques that 
may be useful in mobile application development. Below is an example of 
it. If you are interested, I can share more, but let me know if you have 
specific problem/areas you want to work on.

Thanks,
Tadashi

Note that the table contains 1 column. In the column several fields are 
rendered. This is one of the technique effective on small screen.

<?xml version='1.0' encoding='windows-1252'?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.1"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:trh="http://myfaces.apache.org/trinidad/html"
          xmlns:tr="http://myfaces.apache.org/trinidad">
  <jsp:output omit-xml-declaration="true" doctype-root-element="HTML"
              doctype-system="http://www.w3.org/TR/html4/loose.dtd"
              doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/>
  <jsp:directive.page contentType="text/html;charset=windows-1252"/>
  <f:view>
    <trh:html>
      <trh:head title="mybank Online">
        <meta http-equiv="Content-Type"
              content="text/html; charset=windows-1252"/>
        <f:verbatim rendered="#{AgentUtil.phoneFamily == 'BB4_6Family' ? 
'true' : 'false'}">
            <meta name="viewport" content="width=device-width; 
initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
        </f:verbatim>
        <f:verbatim rendered="#{AgentUtil.phoneFamily == 'iphoneFamily' 
? 'true' : 'false'}">
            <meta name="viewport" content="width=320; initial-scale=1.0; 
maximum-scale=1.0; user-scalable=0;"/>
        </f:verbatim>
      </trh:head>
      <trh:body>
        <!--tr:messages/-->
        <h:form>
          <tr:image source="/images/mybankbandnarrow.gif"/>
          <tr:panelHeader styleClass="toolbar" text="Accounts">
            <tr:commandLink text="Sign Off" styleClass="button"
                            action="signoff"></tr:commandLink>
          </tr:panelHeader>
          <div id="certlist" class="panelBase">
            <tr:commandButton styleClass="button1" text="Transfer.."
                              action="transfer"/>
            <tr:spacer rendered="#{AgentUtil.needSpacer}"
                       height="5" width="15"/>
            <tr:commandButton styleClass="button1" text="Billpay.."
                              action="billpay"/>
            
            <tr:table value="#{bindings.AccountView1.collectionModel}"
                      styleClass="multirowTable" 
horizontalGridVisible="false"
                      var="row" rows="5"
                      emptyText="#{bindings.AccountView1.viewable ? 'No 
data to display.' : 'Access Denied.'}"
                      width="100%">
              <tr:column>
                <tr:panelGroupLayout 
layout="#{AgentUtil.phoneFamilyDebug=='minimalFamily' ? 'horizontal' : 
'vertical'}"
                                     styleClass="listing">
                  <tr:image styleClass="listingImage"
                            
source="#{row.bindings.TypeIconUrl.inputValue} != '' ? 
#{row.bindings.TypeIconUrl.inputValue} : "/>
                  <tr:commandLink text="#{row.bindings.Name.inputValue}"
                                  action="detail" styleClass="listingLink">
                    <tr:setActionListener 
from="#{row.bindings.AccountId.inputValue}"
                                          to="#{sessionScope.accountId}"/>
                  </tr:commandLink>
                  <tr:spacer rendered="#{AgentUtil.needSpacer}"
                             height="5" width="5"/>
                  <tr:outputText value="#{row.bindings.Balance.inputValue}"
                                 styleClass="listingDetails">
                    <f:converter converterId="Bank10.amountConverter"/>
                  </tr:outputText>
                </tr:panelGroupLayout>
              </tr:column>
            </tr:table>
            <tr:separator/>
            
            <tr:commandButton styleClass="button1" text="Find ATM"
                              action="ATM"/>
            
            <tr:spacer rendered="#{AgentUtil.needSpacer}"
                       height="5" width="15"/>
            <tr:commandButton styleClass="button1" text="Find Branch"
                              action="branches"/>
          </div>
          <tr:image source="/images/mybankbandnarrow.gif"/>
        </h:form>
      </trh:body>
    </trh:html>
  </f:view>
</jsp:root>

AgentUtil.java
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;

public class AgentUtil {
    private String phoneFamily;
    private String BLACKBERRY4_2_SKIN  = "BB4_2Family";
    private String BLACKBERRY4_6_SKIN  = "BB4_6Family";
    /* We will use common skin for both 4_6 and 4_7
     */
    private String BLACKBERRY4_7_SKIN  = "BB4_6Family";
    private String IPHONE_SKIN         = "iphoneFamily";
    private String WINDOWS_FAMILY      = "windowsFamily";
    private String SYMBIAN_SKIN        = "symbianFamily";
    private String FIREFOX_SKIN        = "firefoxFamily";
    private String DEFAULT_SKIN        = "minimalFamily";
    private String phoneFamilyDebug;
    private boolean narrowScreen;
    private boolean forceWideScreen = false;
    private boolean supportsDVT_PNG;
    private boolean needSpacer;

    public AgentUtil() {
        phoneFamily = "";
        phoneFamily=getPhoneFamily();
        narrowScreen=getNarrowScreen();
    }

    /**
     * Used for skinning. Can be used in page definition for
     * agent specific rendering.
     */
    public String getPhoneFamily() {
        if (phoneFamily.isEmpty())
        {
            FacesContext fc = FacesContext.getCurrentInstance();
            HttpServletRequest req =
                (HttpServletRequest)fc.getExternalContext().getRequest();
            String agent = req.getHeader("User-Agent");
            System.out.println(agent);
           
            if (agent != null && agent.indexOf("iPhone") > -1) {
                phoneFamily = IPHONE_SKIN;
            } else if (agent != null && agent.indexOf("Symbian") > -1) {
                phoneFamily = SYMBIAN_SKIN;
            } else if (agent != null && agent.indexOf("iPhone") > -1) {
                phoneFamily = IPHONE_SKIN;
            } else if (agent != null && agent.indexOf("WebKit") > -1) {
                phoneFamily = IPHONE_SKIN;
            } else if (agent != null && agent.indexOf("BlackBerry95") > 
-1) {
                System.out.println("BlackBerry9x");
                phoneFamily = BLACKBERRY4_7_SKIN;
            } else if (agent != null && agent.indexOf("BlackBerry90") > 
-1) {
                System.out.println("BlackBerry9x");
                phoneFamily = BLACKBERRY4_6_SKIN;
            } else if (agent != null && agent.indexOf("BlackBerry88") > 
-1) {
                phoneFamily = DEFAULT_SKIN;
                forceWideScreen = true;
            } else if (agent != null && agent.indexOf("BlackBerry83") > 
-1) {
                phoneFamily = DEFAULT_SKIN;
                forceWideScreen = true;
            } else if (agent != null && agent.indexOf("BlackBerry") > -1) {
                phoneFamily = DEFAULT_SKIN;
            } else if (agent != null && agent.indexOf("Windows CE") > -1) {
                phoneFamily = WINDOWS_FAMILY;
            } else if (agent != null && agent.indexOf("Firefox") > -1) {
                phoneFamily = FIREFOX_SKIN;
            } else {
                phoneFamily = DEFAULT_SKIN;
            }
        }
        System.out.println(phoneFamily);
        return phoneFamily;
    }

    public void setPhoneFamily(String phoneFamily) {
        this.phoneFamily = phoneFamily;
    }

    public void setPhoneFamilyDebug(String phoneFamilyDebug) {
        this.phoneFamilyDebug = phoneFamilyDebug;
    }

    /**
     * @return
     */
    public String getPhoneFamilyDebug() {
        String _phoneFamily = getPhoneFamily();
        if (_phoneFamily.equals(FIREFOX_SKIN) || 
(_phoneFamily.equals(DEFAULT_SKIN)))
            return DEFAULT_SKIN;
        else
            return _phoneFamily;
    }

    public void setNarrowScreen(boolean narrowScreen) {
        this.narrowScreen = narrowScreen;
    }

    public boolean getNarrowScreen() {
        return (forceWideScreen==false && getPhoneFamily()==DEFAULT_SKIN);
    }

    public void setSupportsDVT_PNG(boolean supportsDVT_PNG) {
        this.supportsDVT_PNG = supportsDVT_PNG;
    }

    public boolean getSupportsDVT_PNG() {
        String _phoneFamily = getPhoneFamily();
        if (_phoneFamily.equals(DEFAULT_SKIN)) {
            return false;
            }
        return true;
    }

    public void setNeedSpacer(boolean needSpacer) {
        this.needSpacer = needSpacer;
    }

    public boolean getNeedSpacer()
    {
        String _phoneFamily = getPhoneFamily();

        if ((_phoneFamily.equals(DEFAULT_SKIN)) &&
                            !this.getNarrowScreen())
        {
            return true;
        }
        return false;
    }
}


aurel.sandu@vectorsoftware.ro wrote:
> Hello,
> I have read about rendering Trinidad apps to blackberry devices. Can you give me some
links to read about this (some examples , some fragments code from implementation maybe)?
> Best regards,
> Aurel
>
>   


Mime
View raw message